1 /* Invoke the system diff tool to compare two strings.
2    Copyright (C) 2016-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <support/run_diff.h>
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <support/check.h>
25 #include <support/support.h>
26 #include <support/temp_file.h>
27 #include <support/xunistd.h>
28 #include <sys/wait.h>
29 
30 static char *
write_to_temp_file(const char * prefix,const char * str)31 write_to_temp_file (const char *prefix, const char *str)
32 {
33   char *template = xasprintf ("run_diff-%s", prefix);
34   char *name = NULL;
35   int fd = create_temp_file (template, &name);
36   TEST_VERIFY_EXIT (fd >= 0);
37   free (template);
38   xwrite (fd, str, strlen (str));
39   xclose (fd);
40   return name;
41 }
42 
43 void
support_run_diff(const char * left_label,const char * left,const char * right_label,const char * right)44 support_run_diff (const char *left_label, const char *left,
45                   const char *right_label, const char *right)
46 {
47   /* Ensure that the diff command output is ordered properly with
48      standard output.  */
49   TEST_VERIFY_EXIT (fflush (stdout) == 0);
50 
51   char *left_path = write_to_temp_file ("left-diff", left);
52   char *right_path = write_to_temp_file ("right-diff", right);
53 
54   pid_t pid = xfork ();
55   if (pid == 0)
56     {
57       execlp ("diff", "diff", "-u",
58               "--label", left_label, "--label", right_label,
59               "--", left_path, right_path,
60               NULL);
61       _exit (17);
62     }
63   else
64     {
65       int status;
66       xwaitpid (pid, &status, 0);
67       if (!WIFEXITED (status) || WEXITSTATUS (status) != 1)
68         printf ("warning: could not run diff, exit status: %d\n"
69                 "*** %s ***\n%s\n"
70                 "*** %s ***\n%s\n",
71                 status, left_label, left, right_label, right);
72     }
73 
74   free (right_path);
75   free (left_path);
76 }
77