f10cc95fe51f1eaa65d8e38b15e5d4992f2db6f2
[gnulib.git] / lib / pipe.c
1 /* Creation of subprocesses, communicating via pipes.
2    Copyright (C) 2001-2004, 2006-2007 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 "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 "wait-process.h"
33 #include "gettext.h"
34
35 #define _(str) gettext (str)
36
37 #if defined _MSC_VER || defined __MINGW32__
38
39 /* Native Woe32 API.  */
40 # include <process.h>
41 # include "w32spawn.h"
42
43 #else
44
45 /* Unix API.  */
46 # if HAVE_POSIX_SPAWN
47 #  include <spawn.h>
48 # else
49 #  if HAVE_VFORK_H
50 #   include <vfork.h>
51 #  endif
52 # endif
53
54 #endif
55
56 #if ! HAVE_ENVIRON_DECL
57 extern char **environ;
58 #endif
59
60 #ifndef STDIN_FILENO
61 # define STDIN_FILENO 0
62 #endif
63 #ifndef STDOUT_FILENO
64 # define STDOUT_FILENO 1
65 #endif
66 #ifndef STDERR_FILENO
67 # define STDERR_FILENO 2
68 #endif
69
70 /* The results of open() in this file are not used with fchdir,
71    therefore save some unnecessary work in fchdir.c.  */
72 #undef open
73 #undef close
74
75
76 #ifdef EINTR
77
78 /* EINTR handling for close().
79    These functions can return -1/EINTR even though we don't have any
80    signal handlers set up, namely when we get interrupted via SIGSTOP.  */
81
82 static inline int
83 nonintr_close (int fd)
84 {
85   int retval;
86
87   do
88     retval = close (fd);
89   while (retval < 0 && errno == EINTR);
90
91   return retval;
92 }
93 #define close nonintr_close
94
95 static inline int
96 nonintr_open (const char *pathname, int oflag, mode_t mode)
97 {
98   int retval;
99
100   do
101     retval = open (pathname, oflag, mode);
102   while (retval < 0 && errno == EINTR);
103
104   return retval;
105 }
106 #undef open /* avoid warning on VMS */
107 #define open nonintr_open
108
109 #endif
110
111
112 /* Open a pipe connected to a child process.
113  *
114  *           write       system                read
115  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child       if pipe_stdin
116  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child       if pipe_stdout
117  *           read        system                write
118  *
119  * At least one of pipe_stdin, pipe_stdout must be true.
120  * pipe_stdin and prog_stdin together determine the child's standard input.
121  * pipe_stdout and prog_stdout together determine the child's standard output.
122  * If pipe_stdin is true, prog_stdin is ignored.
123  * If pipe_stdout is true, prog_stdout is ignored.
124  */
125 static pid_t
126 create_pipe (const char *progname,
127              const char *prog_path, char **prog_argv,
128              bool pipe_stdin, bool pipe_stdout,
129              const char *prog_stdin, const char *prog_stdout,
130              bool null_stderr,
131              bool slave_process, bool exit_on_error,
132              int fd[2])
133 {
134 #if defined _MSC_VER || defined __MINGW32__
135
136   /* Native Woe32 API.
137      This uses _pipe(), dup2(), and spawnv().  It could also be implemented
138      using the low-level functions CreatePipe(), DuplicateHandle(),
139      CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
140      and cvs source code.  */
141   int ifd[2];
142   int ofd[2];
143   int orig_stdin;
144   int orig_stdout;
145   int orig_stderr;
146   int child;
147   int nulloutfd;
148   int stdinfd;
149   int stdoutfd;
150
151   prog_argv = prepare_spawn (prog_argv);
152
153   if (pipe_stdout)
154     if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0)
155       error (EXIT_FAILURE, errno, _("cannot create pipe"));
156   if (pipe_stdin)
157     if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0)
158       error (EXIT_FAILURE, errno, _("cannot create pipe"));
159 /* Data flow diagram:
160  *
161  *           write        system         read
162  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
163  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
164  *           read         system         write
165  *
166  */
167
168   /* Save standard file handles of parent process.  */
169   if (pipe_stdin || prog_stdin != NULL)
170     orig_stdin = dup_noinherit (STDIN_FILENO);
171   if (pipe_stdout || prog_stdout != NULL)
172     orig_stdout = dup_noinherit (STDOUT_FILENO);
173   if (null_stderr)
174     orig_stderr = dup_noinherit (STDERR_FILENO);
175   child = -1;
176
177   /* Create standard file handles of child process.  */
178   nulloutfd = -1;
179   stdinfd = -1;
180   stdoutfd = -1;
181   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
182       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
183       && (!null_stderr
184           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
185               && (nulloutfd == STDERR_FILENO
186                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
187                       && close (nulloutfd) >= 0))))
188       && (pipe_stdin
189           || prog_stdin == NULL
190           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
191               && (stdinfd == STDIN_FILENO
192                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
193                       && close (stdinfd) >= 0))))
194       && (pipe_stdout
195           || prog_stdout == NULL
196           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
197               && (stdoutfd == STDOUT_FILENO
198                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
199                       && close (stdoutfd) >= 0)))))
200     /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
201        but it inherits all open()ed or dup2()ed file handles (which is what
202        we want in the case of STD*_FILENO) and also orig_stdin,
203        orig_stdout, orig_stderr (which is not explicitly wanted but
204        harmless).  */
205     child = spawnvp (P_NOWAIT, prog_path, prog_argv);
206   if (stdinfd >= 0)
207     close (stdinfd);
208   if (stdoutfd >= 0)
209     close (stdoutfd);
210   if (nulloutfd >= 0)
211     close (nulloutfd);
212
213   /* Restore standard file handles of parent process.  */
214   if (null_stderr)
215     dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
216   if (pipe_stdout || prog_stdout != NULL)
217     dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
218   if (pipe_stdin || prog_stdin != NULL)
219     dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
220
221   if (pipe_stdin)
222     close (ofd[0]);
223   if (pipe_stdout)
224     close (ifd[1]);
225   if (child == -1)
226     {
227       if (exit_on_error || !null_stderr)
228         error (exit_on_error ? EXIT_FAILURE : 0, errno,
229                _("%s subprocess failed"), progname);
230       if (pipe_stdout)
231         close (ifd[0]);
232       if (pipe_stdin)
233         close (ofd[1]);
234       return -1;
235     }
236
237   if (pipe_stdout)
238     fd[0] = ifd[0];
239   if (pipe_stdin)
240     fd[1] = ofd[1];
241   return child;
242
243 #else
244
245   /* Unix API.  */
246   int ifd[2];
247   int ofd[2];
248 # if HAVE_POSIX_SPAWN
249   sigset_t blocked_signals;
250   posix_spawn_file_actions_t actions;
251   bool actions_allocated;
252   posix_spawnattr_t attrs;
253   bool attrs_allocated;
254   int err;
255   pid_t child;
256 # else
257   int child;
258 # endif
259
260   if (pipe_stdout)
261     if (pipe (ifd) < 0)
262       error (EXIT_FAILURE, errno, _("cannot create pipe"));
263   if (pipe_stdin)
264     if (pipe (ofd) < 0)
265       error (EXIT_FAILURE, errno, _("cannot create pipe"));
266 /* Data flow diagram:
267  *
268  *           write        system         read
269  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
270  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
271  *           read         system         write
272  *
273  */
274
275 # if HAVE_POSIX_SPAWN
276   if (slave_process)
277     {
278       sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
279       block_fatal_signals ();
280     }
281   actions_allocated = false;
282   attrs_allocated = false;
283   if ((err = posix_spawn_file_actions_init (&actions)) != 0
284       || (actions_allocated = true,
285           (pipe_stdin
286            && (err = posix_spawn_file_actions_adddup2 (&actions,
287                                                        ofd[0], STDIN_FILENO))
288               != 0)
289           || (pipe_stdout
290               && (err = posix_spawn_file_actions_adddup2 (&actions,
291                                                           ifd[1], STDOUT_FILENO))
292                  != 0)
293           || (pipe_stdin
294               && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
295                  != 0)
296           || (pipe_stdout
297               && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
298                  != 0)
299           || (pipe_stdin
300               && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
301                  != 0)
302           || (pipe_stdout
303               && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
304                  != 0)
305           || (null_stderr
306               && (err = posix_spawn_file_actions_addopen (&actions,
307                                                           STDERR_FILENO,
308                                                           "/dev/null", O_RDWR,
309                                                           0))
310                  != 0)
311           || (!pipe_stdin
312               && prog_stdin != NULL
313               && (err = posix_spawn_file_actions_addopen (&actions,
314                                                           STDIN_FILENO,
315                                                           prog_stdin, O_RDONLY,
316                                                           0))
317                  != 0)
318           || (!pipe_stdout
319               && prog_stdout != NULL
320               && (err = posix_spawn_file_actions_addopen (&actions,
321                                                           STDOUT_FILENO,
322                                                           prog_stdout, O_WRONLY,
323                                                           0))
324                  != 0)
325           || (slave_process
326               && ((err = posix_spawnattr_init (&attrs)) != 0
327                   || (attrs_allocated = true,
328                       (err = posix_spawnattr_setsigmask (&attrs,
329                                                          &blocked_signals))
330                       != 0
331                       || (err = posix_spawnattr_setflags (&attrs,
332                                                         POSIX_SPAWN_SETSIGMASK))
333                          != 0)))
334           || (err = posix_spawnp (&child, prog_path, &actions,
335                                   attrs_allocated ? &attrs : NULL, prog_argv,
336                                   environ))
337              != 0))
338     {
339       if (actions_allocated)
340         posix_spawn_file_actions_destroy (&actions);
341       if (attrs_allocated)
342         posix_spawnattr_destroy (&attrs);
343       if (slave_process)
344         unblock_fatal_signals ();
345       if (exit_on_error || !null_stderr)
346         error (exit_on_error ? EXIT_FAILURE : 0, err,
347                _("%s subprocess failed"), progname);
348       if (pipe_stdout)
349         {
350           close (ifd[0]);
351           close (ifd[1]);
352         }
353       if (pipe_stdin)
354         {
355           close (ofd[0]);
356           close (ofd[1]);
357         }
358       return -1;
359     }
360   posix_spawn_file_actions_destroy (&actions);
361   if (attrs_allocated)
362     posix_spawnattr_destroy (&attrs);
363 # else
364   if (slave_process)
365     block_fatal_signals ();
366   /* Use vfork() instead of fork() for efficiency.  */
367   if ((child = vfork ()) == 0)
368     {
369       /* Child process code.  */
370       int nulloutfd;
371       int stdinfd;
372       int stdoutfd;
373
374       if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
375           && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
376           && (!pipe_stdin || close (ofd[0]) >= 0)
377           && (!pipe_stdout || close (ifd[1]) >= 0)
378           && (!pipe_stdin || close (ofd[1]) >= 0)
379           && (!pipe_stdout || close (ifd[0]) >= 0)
380           && (!null_stderr
381               || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
382                   && (nulloutfd == STDERR_FILENO
383                       || (dup2 (nulloutfd, STDERR_FILENO) >= 0
384                           && close (nulloutfd) >= 0))))
385           && (pipe_stdin
386               || prog_stdin == NULL
387               || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
388                   && (stdinfd == STDIN_FILENO
389                       || (dup2 (stdinfd, STDIN_FILENO) >= 0
390                           && close (stdinfd) >= 0))))
391           && (pipe_stdout
392               || prog_stdout == NULL
393               || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
394                   && (stdoutfd == STDOUT_FILENO
395                       || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
396                           && close (stdoutfd) >= 0))))
397           && (!slave_process || (unblock_fatal_signals (), true)))
398         execvp (prog_path, prog_argv);
399       _exit (127);
400     }
401   if (child == -1)
402     {
403       if (slave_process)
404         unblock_fatal_signals ();
405       if (exit_on_error || !null_stderr)
406         error (exit_on_error ? EXIT_FAILURE : 0, errno,
407                _("%s subprocess failed"), progname);
408       if (pipe_stdout)
409         {
410           close (ifd[0]);
411           close (ifd[1]);
412         }
413       if (pipe_stdin)
414         {
415           close (ofd[0]);
416           close (ofd[1]);
417         }
418       return -1;
419     }
420 # endif
421   if (slave_process)
422     {
423       register_slave_subprocess (child);
424       unblock_fatal_signals ();
425     }
426   if (pipe_stdin)
427     close (ofd[0]);
428   if (pipe_stdout)
429     close (ifd[1]);
430
431   if (pipe_stdout)
432     fd[0] = ifd[0];
433   if (pipe_stdin)
434     fd[1] = ofd[1];
435   return child;
436
437 #endif
438 }
439
440 /* Open a bidirectional pipe.
441  *
442  *           write       system                read
443  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child
444  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
445  *           read        system                write
446  *
447  */
448 pid_t
449 create_pipe_bidi (const char *progname,
450                   const char *prog_path, char **prog_argv,
451                   bool null_stderr,
452                   bool slave_process, bool exit_on_error,
453                   int fd[2])
454 {
455   pid_t result = create_pipe (progname, prog_path, prog_argv,
456                               true, true, NULL, NULL,
457                               null_stderr, slave_process, exit_on_error,
458                               fd);
459   return result;
460 }
461
462 /* Open a pipe for input from a child process.
463  * The child's stdin comes from a file.
464  *
465  *           read        system                write
466  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
467  *
468  */
469 pid_t
470 create_pipe_in (const char *progname,
471                 const char *prog_path, char **prog_argv,
472                 const char *prog_stdin, bool null_stderr,
473                 bool slave_process, bool exit_on_error,
474                 int fd[1])
475 {
476   int iofd[2];
477   pid_t result = create_pipe (progname, prog_path, prog_argv,
478                               false, true, prog_stdin, NULL,
479                               null_stderr, slave_process, exit_on_error,
480                               iofd);
481   if (result != -1)
482     fd[0] = iofd[0];
483   return result;
484 }
485
486 /* Open a pipe for output to a child process.
487  * The child's stdout goes to a file.
488  *
489  *           write       system                read
490  *    parent  ->   fd[0]   ->   STDIN_FILENO    ->   child
491  *
492  */
493 pid_t
494 create_pipe_out (const char *progname,
495                  const char *prog_path, char **prog_argv,
496                  const char *prog_stdout, bool null_stderr,
497                  bool slave_process, bool exit_on_error,
498                  int fd[1])
499 {
500   int iofd[2];
501   pid_t result = create_pipe (progname, prog_path, prog_argv,
502                               true, false, NULL, prog_stdout,
503                               null_stderr, slave_process, exit_on_error,
504                               iofd);
505   if (result != -1)
506     fd[0] = iofd[1];
507   return result;
508 }