1 /* Creation of subprocesses, communicating via pipes.
2    Copyright (C) 2001-2004, 2006-2020 Free Software Foundation, Inc.
3    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4 
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9 
10    This program 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
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17 
18 
19 /* Tell clang not to warn about the 'child' variable, below.  */
20 #if defined __clang__
21 # pragma clang diagnostic ignored "-Wconditional-uninitialized"
22 #endif
23 
24 #include <config.h>
25 
26 /* Specification.  */
27 #include "spawn-pipe.h"
28 
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <signal.h>
33 #include <unistd.h>
34 
35 #include "error.h"
36 #include "fatal-signal.h"
37 #include "unistd-safer.h"
38 #include "wait-process.h"
39 #include "gettext.h"
40 
41 #define _(str) gettext (str)
42 
43 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
44 
45 /* Native Windows API.  */
46 # include <process.h>
47 # include "w32spawn.h"
48 
49 #else
50 
51 /* Unix API.  */
52 # include <spawn.h>
53 
54 #endif
55 
56 
57 #ifdef EINTR
58 
59 /* EINTR handling for close().
60    These functions can return -1/EINTR even though we don't have any
61    signal handlers set up, namely when we get interrupted via SIGSTOP.  */
62 
63 static int
nonintr_close(int fd)64 nonintr_close (int fd)
65 {
66   int retval;
67 
68   do
69     retval = close (fd);
70   while (retval < 0 && errno == EINTR);
71 
72   return retval;
73 }
74 #undef close /* avoid warning related to gnulib module unistd */
75 #define close nonintr_close
76 
77 #if defined _WIN32 && ! defined __CYGWIN__
78 static int
nonintr_open(const char * pathname,int oflag,mode_t mode)79 nonintr_open (const char *pathname, int oflag, mode_t mode)
80 {
81   int retval;
82 
83   do
84     retval = open (pathname, oflag, mode);
85   while (retval < 0 && errno == EINTR);
86 
87   return retval;
88 }
89 # undef open /* avoid warning on VMS */
90 # define open nonintr_open
91 #endif
92 
93 #endif
94 
95 
96 /* Open a pipe connected to a child process.
97  *
98  *           write       system                read
99  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child       if pipe_stdin
100  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child       if pipe_stdout
101  *           read        system                write
102  *
103  * At least one of pipe_stdin, pipe_stdout must be true.
104  * pipe_stdin and prog_stdin together determine the child's standard input.
105  * pipe_stdout and prog_stdout together determine the child's standard output.
106  * If pipe_stdin is true, prog_stdin is ignored.
107  * If pipe_stdout is true, prog_stdout is ignored.
108  */
109 static pid_t
create_pipe(const char * progname,const char * prog_path,char ** prog_argv,bool pipe_stdin,bool pipe_stdout,const char * prog_stdin,const char * prog_stdout,bool null_stderr,bool slave_process,bool exit_on_error,int fd[2])110 create_pipe (const char *progname,
111              const char *prog_path, char **prog_argv,
112              bool pipe_stdin, bool pipe_stdout,
113              const char *prog_stdin, const char *prog_stdout,
114              bool null_stderr,
115              bool slave_process, bool exit_on_error,
116              int fd[2])
117 {
118 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
119 
120   /* Native Windows API.
121      This uses _pipe(), dup2(), and spawnv().  It could also be implemented
122      using the low-level functions CreatePipe(), DuplicateHandle(),
123      CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
124      and cvs source code.  */
125   int ifd[2];
126   int ofd[2];
127   int orig_stdin;
128   int orig_stdout;
129   int orig_stderr;
130   int child;
131   int nulloutfd;
132   int stdinfd;
133   int stdoutfd;
134   int saved_errno;
135 
136   /* FIXME: Need to free memory allocated by prepare_spawn.  */
137   prog_argv = prepare_spawn (prog_argv);
138 
139   if (pipe_stdout)
140     if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
141       error (EXIT_FAILURE, errno, _("cannot create pipe"));
142   if (pipe_stdin)
143     if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
144       error (EXIT_FAILURE, errno, _("cannot create pipe"));
145 /* Data flow diagram:
146  *
147  *           write        system         read
148  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
149  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
150  *           read         system         write
151  *
152  */
153 
154   /* Save standard file handles of parent process.  */
155   if (pipe_stdin || prog_stdin != NULL)
156     orig_stdin = dup_safer_noinherit (STDIN_FILENO);
157   if (pipe_stdout || prog_stdout != NULL)
158     orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
159   if (null_stderr)
160     orig_stderr = dup_safer_noinherit (STDERR_FILENO);
161   child = -1;
162 
163   /* Create standard file handles of child process.  */
164   nulloutfd = -1;
165   stdinfd = -1;
166   stdoutfd = -1;
167   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
168       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
169       && (!null_stderr
170           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
171               && (nulloutfd == STDERR_FILENO
172                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
173                       && close (nulloutfd) >= 0))))
174       && (pipe_stdin
175           || prog_stdin == NULL
176           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
177               && (stdinfd == STDIN_FILENO
178                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
179                       && close (stdinfd) >= 0))))
180       && (pipe_stdout
181           || prog_stdout == NULL
182           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
183               && (stdoutfd == STDOUT_FILENO
184                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
185                       && close (stdoutfd) >= 0)))))
186     /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
187        but it inherits all open()ed or dup2()ed file handles (which is what
188        we want in the case of STD*_FILENO).  */
189     /* Use spawnvpe and pass the environment explicitly.  This is needed if
190        the program has modified the environment using putenv() or [un]setenv().
191        On Windows, programs have two environments, one in the "environment
192        block" of the process and managed through SetEnvironmentVariable(), and
193        one inside the process, in the location retrieved by the 'environ'
194        macro.  When using spawnvp() without 'e', the child process inherits a
195        copy of the environment block - ignoring the effects of putenv() and
196        [un]setenv().  */
197     {
198       child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
199                         (const char **) environ);
200       if (child < 0 && errno == ENOEXEC)
201         {
202           /* prog is not a native executable.  Try to execute it as a
203              shell script.  Note that prepare_spawn() has already prepended
204              a hidden element "sh.exe" to prog_argv.  */
205           --prog_argv;
206           child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
207                             (const char **) environ);
208         }
209     }
210   if (child == -1)
211     saved_errno = errno;
212   if (stdinfd >= 0)
213     close (stdinfd);
214   if (stdoutfd >= 0)
215     close (stdoutfd);
216   if (nulloutfd >= 0)
217     close (nulloutfd);
218 
219   /* Restore standard file handles of parent process.  */
220   if (null_stderr)
221     undup_safer_noinherit (orig_stderr, STDERR_FILENO);
222   if (pipe_stdout || prog_stdout != NULL)
223     undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
224   if (pipe_stdin || prog_stdin != NULL)
225     undup_safer_noinherit (orig_stdin, STDIN_FILENO);
226 
227   if (pipe_stdin)
228     close (ofd[0]);
229   if (pipe_stdout)
230     close (ifd[1]);
231   if (child == -1)
232     {
233       if (exit_on_error || !null_stderr)
234         error (exit_on_error ? EXIT_FAILURE : 0, saved_errno,
235                _("%s subprocess failed"), progname);
236       if (pipe_stdout)
237         close (ifd[0]);
238       if (pipe_stdin)
239         close (ofd[1]);
240       errno = saved_errno;
241       return -1;
242     }
243 
244   if (pipe_stdout)
245     fd[0] = ifd[0];
246   if (pipe_stdin)
247     fd[1] = ofd[1];
248   return child;
249 
250 #else
251 
252   /* Unix API.  */
253   int ifd[2];
254   int ofd[2];
255   sigset_t blocked_signals;
256   posix_spawn_file_actions_t actions;
257   bool actions_allocated;
258   posix_spawnattr_t attrs;
259   bool attrs_allocated;
260   int err;
261   pid_t child;
262 
263   if (pipe_stdout)
264     if (pipe_safer (ifd) < 0)
265       error (EXIT_FAILURE, errno, _("cannot create pipe"));
266   if (pipe_stdin)
267     if (pipe_safer (ofd) < 0)
268       error (EXIT_FAILURE, errno, _("cannot create pipe"));
269 /* Data flow diagram:
270  *
271  *           write        system         read
272  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
273  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
274  *           read         system         write
275  *
276  */
277 
278   if (slave_process)
279     {
280       sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
281       block_fatal_signals ();
282     }
283   actions_allocated = false;
284   attrs_allocated = false;
285   if ((err = posix_spawn_file_actions_init (&actions)) != 0
286       || (actions_allocated = true,
287           (pipe_stdin
288            && (err = posix_spawn_file_actions_adddup2 (&actions,
289                                                        ofd[0], STDIN_FILENO))
290               != 0)
291           || (pipe_stdout
292               && (err = posix_spawn_file_actions_adddup2 (&actions,
293                                                           ifd[1], STDOUT_FILENO))
294                  != 0)
295           || (pipe_stdin
296               && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
297                  != 0)
298           || (pipe_stdout
299               && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
300                  != 0)
301           || (pipe_stdin
302               && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
303                  != 0)
304           || (pipe_stdout
305               && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
306                  != 0)
307           || (null_stderr
308               && (err = posix_spawn_file_actions_addopen (&actions,
309                                                           STDERR_FILENO,
310                                                           "/dev/null", O_RDWR,
311                                                           0))
312                  != 0)
313           || (!pipe_stdin
314               && prog_stdin != NULL
315               && (err = posix_spawn_file_actions_addopen (&actions,
316                                                           STDIN_FILENO,
317                                                           prog_stdin, O_RDONLY,
318                                                           0))
319                  != 0)
320           || (!pipe_stdout
321               && prog_stdout != NULL
322               && (err = posix_spawn_file_actions_addopen (&actions,
323                                                           STDOUT_FILENO,
324                                                           prog_stdout, O_WRONLY,
325                                                           0))
326                  != 0)
327           || (slave_process
328               && ((err = posix_spawnattr_init (&attrs)) != 0
329                   || (attrs_allocated = true,
330                       (err = posix_spawnattr_setsigmask (&attrs,
331                                                          &blocked_signals))
332                       != 0
333                       || (err = posix_spawnattr_setflags (&attrs,
334                                                         POSIX_SPAWN_SETSIGMASK))
335                          != 0)))
336           || (err = posix_spawnp (&child, prog_path, &actions,
337                                   attrs_allocated ? &attrs : NULL, prog_argv,
338                                   environ))
339              != 0))
340     {
341       if (actions_allocated)
342         posix_spawn_file_actions_destroy (&actions);
343       if (attrs_allocated)
344         posix_spawnattr_destroy (&attrs);
345       if (slave_process)
346         unblock_fatal_signals ();
347       if (exit_on_error || !null_stderr)
348         error (exit_on_error ? EXIT_FAILURE : 0, err,
349                _("%s subprocess failed"), progname);
350       if (pipe_stdout)
351         {
352           close (ifd[0]);
353           close (ifd[1]);
354         }
355       if (pipe_stdin)
356         {
357           close (ofd[0]);
358           close (ofd[1]);
359         }
360       errno = err;
361       return -1;
362     }
363   posix_spawn_file_actions_destroy (&actions);
364   if (attrs_allocated)
365     posix_spawnattr_destroy (&attrs);
366   if (slave_process)
367     {
368       register_slave_subprocess (child);
369       unblock_fatal_signals ();
370     }
371   if (pipe_stdin)
372     close (ofd[0]);
373   if (pipe_stdout)
374     close (ifd[1]);
375 
376   if (pipe_stdout)
377     fd[0] = ifd[0];
378   if (pipe_stdin)
379     fd[1] = ofd[1];
380   return child;
381 
382 #endif
383 }
384 
385 /* Open a bidirectional pipe.
386  *
387  *           write       system                read
388  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child
389  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
390  *           read        system                write
391  *
392  */
393 pid_t
create_pipe_bidi(const char * progname,const char * prog_path,char ** prog_argv,bool null_stderr,bool slave_process,bool exit_on_error,int fd[2])394 create_pipe_bidi (const char *progname,
395                   const char *prog_path, char **prog_argv,
396                   bool null_stderr,
397                   bool slave_process, bool exit_on_error,
398                   int fd[2])
399 {
400   pid_t result = create_pipe (progname, prog_path, prog_argv,
401                               true, true, NULL, NULL,
402                               null_stderr, slave_process, exit_on_error,
403                               fd);
404   return result;
405 }
406 
407 /* Open a pipe for input from a child process.
408  * The child's stdin comes from a file.
409  *
410  *           read        system                write
411  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
412  *
413  */
414 pid_t
create_pipe_in(const char * progname,const char * prog_path,char ** prog_argv,const char * prog_stdin,bool null_stderr,bool slave_process,bool exit_on_error,int fd[1])415 create_pipe_in (const char *progname,
416                 const char *prog_path, char **prog_argv,
417                 const char *prog_stdin, bool null_stderr,
418                 bool slave_process, bool exit_on_error,
419                 int fd[1])
420 {
421   int iofd[2];
422   pid_t result = create_pipe (progname, prog_path, prog_argv,
423                               false, true, prog_stdin, NULL,
424                               null_stderr, slave_process, exit_on_error,
425                               iofd);
426   if (result != -1)
427     fd[0] = iofd[0];
428   return result;
429 }
430 
431 /* Open a pipe for output to a child process.
432  * The child's stdout goes to a file.
433  *
434  *           write       system                read
435  *    parent  ->   fd[0]   ->   STDIN_FILENO    ->   child
436  *
437  */
438 pid_t
create_pipe_out(const char * progname,const char * prog_path,char ** prog_argv,const char * prog_stdout,bool null_stderr,bool slave_process,bool exit_on_error,int fd[1])439 create_pipe_out (const char *progname,
440                  const char *prog_path, char **prog_argv,
441                  const char *prog_stdout, bool null_stderr,
442                  bool slave_process, bool exit_on_error,
443                  int fd[1])
444 {
445   int iofd[2];
446   pid_t result = create_pipe (progname, prog_path, prog_argv,
447                               true, false, NULL, prog_stdout,
448                               null_stderr, slave_process, exit_on_error,
449                               iofd);
450   if (result != -1)
451     fd[0] = iofd[1];
452   return result;
453 }
454