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