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