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