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