Use the posix_spawn or its replacement on all Unix platforms.
[gnulib.git] / lib / pipe.c
1 /* Creation of subprocesses, communicating via pipes.
2    Copyright (C) 2001-2004, 2006-2009 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 "unistd-safer.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 # 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 inline int
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 static inline int
77 nonintr_open (const char *pathname, int oflag, mode_t mode)
78 {
79   int retval;
80
81   do
82     retval = open (pathname, oflag, mode);
83   while (retval < 0 && errno == EINTR);
84
85   return retval;
86 }
87 #undef open /* avoid warning on VMS */
88 #define open nonintr_open
89
90 #endif
91
92
93 /* Open a pipe connected to a child process.
94  *
95  *           write       system                read
96  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child       if pipe_stdin
97  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child       if pipe_stdout
98  *           read        system                write
99  *
100  * At least one of pipe_stdin, pipe_stdout must be true.
101  * pipe_stdin and prog_stdin together determine the child's standard input.
102  * pipe_stdout and prog_stdout together determine the child's standard output.
103  * If pipe_stdin is true, prog_stdin is ignored.
104  * If pipe_stdout is true, prog_stdout is ignored.
105  */
106 static pid_t
107 create_pipe (const char *progname,
108              const char *prog_path, char **prog_argv,
109              bool pipe_stdin, bool pipe_stdout,
110              const char *prog_stdin, const char *prog_stdout,
111              bool null_stderr,
112              bool slave_process, bool exit_on_error,
113              int fd[2])
114 {
115 #if defined _MSC_VER || defined __MINGW32__
116
117   /* Native Woe32 API.
118      This uses _pipe(), dup2(), and spawnv().  It could also be implemented
119      using the low-level functions CreatePipe(), DuplicateHandle(),
120      CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
121      and cvs source code.  */
122   int ifd[2];
123   int ofd[2];
124   int orig_stdin;
125   int orig_stdout;
126   int orig_stderr;
127   int child;
128   int nulloutfd;
129   int stdinfd;
130   int stdoutfd;
131
132   /* FIXME: Need to free memory allocated by prepare_spawn.  */
133   prog_argv = prepare_spawn (prog_argv);
134
135   if (pipe_stdout)
136     if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0
137         || (ifd[0] = fd_safer (ifd[0])) < 0)
138       error (EXIT_FAILURE, errno, _("cannot create pipe"));
139   if (pipe_stdin)
140     if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0
141         || (ofd[1] = fd_safer (ofd[1])) < 0)
142       error (EXIT_FAILURE, errno, _("cannot create pipe"));
143 /* Data flow diagram:
144  *
145  *           write        system         read
146  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
147  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
148  *           read         system         write
149  *
150  */
151
152   /* Save standard file handles of parent process.  */
153   if (pipe_stdin || prog_stdin != NULL)
154     orig_stdin = dup_noinherit (STDIN_FILENO);
155   if (pipe_stdout || prog_stdout != NULL)
156     orig_stdout = dup_noinherit (STDOUT_FILENO);
157   if (null_stderr)
158     orig_stderr = dup_noinherit (STDERR_FILENO);
159   child = -1;
160
161   /* Create standard file handles of child process.  */
162   nulloutfd = -1;
163   stdinfd = -1;
164   stdoutfd = -1;
165   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
166       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
167       && (!null_stderr
168           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
169               && (nulloutfd == STDERR_FILENO
170                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
171                       && close (nulloutfd) >= 0))))
172       && (pipe_stdin
173           || prog_stdin == NULL
174           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
175               && (stdinfd == STDIN_FILENO
176                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
177                       && close (stdinfd) >= 0))))
178       && (pipe_stdout
179           || prog_stdout == NULL
180           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
181               && (stdoutfd == STDOUT_FILENO
182                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
183                       && close (stdoutfd) >= 0)))))
184     /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
185        but it inherits all open()ed or dup2()ed file handles (which is what
186        we want in the case of STD*_FILENO) and also orig_stdin,
187        orig_stdout, orig_stderr (which is not explicitly wanted but
188        harmless).  */
189     /* Use spawnvpe and pass the environment explicitly.  This is needed if
190        the program has modified the environment using putenv() or [un]setenv().
191        On Windows, programs have two environments, one in the "environment
192        block" of the process and managed through SetEnvironmentVariable(), and
193        one inside the process, in the location retrieved by the 'environ'
194        macro.  When using spawnvp() without 'e', the child process inherits a
195        copy of the environment block - ignoring the effects of putenv() and
196        [un]setenv().  */
197     {
198       child = spawnvpe (P_NOWAIT, prog_path, prog_argv, environ);
199       if (child < 0 && errno == ENOEXEC)
200         {
201           /* prog is not an 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], prog_argv, environ);
206         }
207     }
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   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
258   if (pipe_stdout)
259     if (pipe (ifd) < 0
260         || (ifd[0] = fd_safer (ifd[0])) < 0)
261       error (EXIT_FAILURE, errno, _("cannot create pipe"));
262   if (pipe_stdin)
263     if (pipe (ofd) < 0
264         || (ofd[1] = fd_safer (ofd[1])) < 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 (slave_process)
276     {
277       sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
278       block_fatal_signals ();
279     }
280   actions_allocated = false;
281   attrs_allocated = false;
282   if ((err = posix_spawn_file_actions_init (&actions)) != 0
283       || (actions_allocated = true,
284           (pipe_stdin
285            && (err = posix_spawn_file_actions_adddup2 (&actions,
286                                                        ofd[0], STDIN_FILENO))
287               != 0)
288           || (pipe_stdout
289               && (err = posix_spawn_file_actions_adddup2 (&actions,
290                                                           ifd[1], STDOUT_FILENO))
291                  != 0)
292           || (pipe_stdin
293               && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
294                  != 0)
295           || (pipe_stdout
296               && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
297                  != 0)
298           || (pipe_stdin
299               && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
300                  != 0)
301           || (pipe_stdout
302               && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
303                  != 0)
304           || (null_stderr
305               && (err = posix_spawn_file_actions_addopen (&actions,
306                                                           STDERR_FILENO,
307                                                           "/dev/null", O_RDWR,
308                                                           0))
309                  != 0)
310           || (!pipe_stdin
311               && prog_stdin != NULL
312               && (err = posix_spawn_file_actions_addopen (&actions,
313                                                           STDIN_FILENO,
314                                                           prog_stdin, O_RDONLY,
315                                                           0))
316                  != 0)
317           || (!pipe_stdout
318               && prog_stdout != NULL
319               && (err = posix_spawn_file_actions_addopen (&actions,
320                                                           STDOUT_FILENO,
321                                                           prog_stdout, O_WRONLY,
322                                                           0))
323                  != 0)
324           || (slave_process
325               && ((err = posix_spawnattr_init (&attrs)) != 0
326                   || (attrs_allocated = true,
327                       (err = posix_spawnattr_setsigmask (&attrs,
328                                                          &blocked_signals))
329                       != 0
330                       || (err = posix_spawnattr_setflags (&attrs,
331                                                         POSIX_SPAWN_SETSIGMASK))
332                          != 0)))
333           || (err = posix_spawnp (&child, prog_path, &actions,
334                                   attrs_allocated ? &attrs : NULL, prog_argv,
335                                   environ))
336              != 0))
337     {
338       if (actions_allocated)
339         posix_spawn_file_actions_destroy (&actions);
340       if (attrs_allocated)
341         posix_spawnattr_destroy (&attrs);
342       if (slave_process)
343         unblock_fatal_signals ();
344       if (exit_on_error || !null_stderr)
345         error (exit_on_error ? EXIT_FAILURE : 0, err,
346                _("%s subprocess failed"), progname);
347       if (pipe_stdout)
348         {
349           close (ifd[0]);
350           close (ifd[1]);
351         }
352       if (pipe_stdin)
353         {
354           close (ofd[0]);
355           close (ofd[1]);
356         }
357       return -1;
358     }
359   posix_spawn_file_actions_destroy (&actions);
360   if (attrs_allocated)
361     posix_spawnattr_destroy (&attrs);
362   if (slave_process)
363     {
364       register_slave_subprocess (child);
365       unblock_fatal_signals ();
366     }
367   if (pipe_stdin)
368     close (ofd[0]);
369   if (pipe_stdout)
370     close (ifd[1]);
371
372   if (pipe_stdout)
373     fd[0] = ifd[0];
374   if (pipe_stdin)
375     fd[1] = ofd[1];
376   return child;
377
378 #endif
379 }
380
381 /* Open a bidirectional pipe.
382  *
383  *           write       system                read
384  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child
385  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
386  *           read        system                write
387  *
388  */
389 pid_t
390 create_pipe_bidi (const char *progname,
391                   const char *prog_path, char **prog_argv,
392                   bool null_stderr,
393                   bool slave_process, bool exit_on_error,
394                   int fd[2])
395 {
396   pid_t result = create_pipe (progname, prog_path, prog_argv,
397                               true, true, NULL, NULL,
398                               null_stderr, slave_process, exit_on_error,
399                               fd);
400   return result;
401 }
402
403 /* Open a pipe for input from a child process.
404  * The child's stdin comes from a file.
405  *
406  *           read        system                write
407  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
408  *
409  */
410 pid_t
411 create_pipe_in (const char *progname,
412                 const char *prog_path, char **prog_argv,
413                 const char *prog_stdin, bool null_stderr,
414                 bool slave_process, bool exit_on_error,
415                 int fd[1])
416 {
417   int iofd[2];
418   pid_t result = create_pipe (progname, prog_path, prog_argv,
419                               false, true, prog_stdin, NULL,
420                               null_stderr, slave_process, exit_on_error,
421                               iofd);
422   if (result != -1)
423     fd[0] = iofd[0];
424   return result;
425 }
426
427 /* Open a pipe for output to a child process.
428  * The child's stdout goes to a file.
429  *
430  *           write       system                read
431  *    parent  ->   fd[0]   ->   STDIN_FILENO    ->   child
432  *
433  */
434 pid_t
435 create_pipe_out (const char *progname,
436                  const char *prog_path, char **prog_argv,
437                  const char *prog_stdout, bool null_stderr,
438                  bool slave_process, bool exit_on_error,
439                  int fd[1])
440 {
441   int iofd[2];
442   pid_t result = create_pipe (progname, prog_path, prog_argv,
443                               true, false, NULL, prog_stdout,
444                               null_stderr, slave_process, exit_on_error,
445                               iofd);
446   if (result != -1)
447     fd[0] = iofd[1];
448   return result;
449 }