maint: update almost all copyright ranges to include 2011
[gnulib.git] / lib / spawn-pipe.c
1 /* Creation of subprocesses, communicating via pipes.
2    Copyright (C) 2001-2004, 2006-2011 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 "spawn-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 _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
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 _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
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   int saved_errno;
132
133   /* FIXME: Need to free memory allocated by prepare_spawn.  */
134   prog_argv = prepare_spawn (prog_argv);
135
136   if (pipe_stdout)
137     if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
138       error (EXIT_FAILURE, errno, _("cannot create pipe"));
139   if (pipe_stdin)
140     if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
141       error (EXIT_FAILURE, errno, _("cannot create pipe"));
142 /* Data flow diagram:
143  *
144  *           write        system         read
145  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
146  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
147  *           read         system         write
148  *
149  */
150
151   /* Save standard file handles of parent process.  */
152   if (pipe_stdin || prog_stdin != NULL)
153     orig_stdin = dup_safer_noinherit (STDIN_FILENO);
154   if (pipe_stdout || prog_stdout != NULL)
155     orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
156   if (null_stderr)
157     orig_stderr = dup_safer_noinherit (STDERR_FILENO);
158   child = -1;
159
160   /* Create standard file handles of child process.  */
161   nulloutfd = -1;
162   stdinfd = -1;
163   stdoutfd = -1;
164   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
165       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
166       && (!null_stderr
167           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
168               && (nulloutfd == STDERR_FILENO
169                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
170                       && close (nulloutfd) >= 0))))
171       && (pipe_stdin
172           || prog_stdin == NULL
173           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
174               && (stdinfd == STDIN_FILENO
175                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
176                       && close (stdinfd) >= 0))))
177       && (pipe_stdout
178           || prog_stdout == NULL
179           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
180               && (stdoutfd == STDOUT_FILENO
181                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
182                       && close (stdoutfd) >= 0)))))
183     /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
184        but it inherits all open()ed or dup2()ed file handles (which is what
185        we want in the case of STD*_FILENO).  */
186     /* Use spawnvpe and pass the environment explicitly.  This is needed if
187        the program has modified the environment using putenv() or [un]setenv().
188        On Windows, programs have two environments, one in the "environment
189        block" of the process and managed through SetEnvironmentVariable(), and
190        one inside the process, in the location retrieved by the 'environ'
191        macro.  When using spawnvp() without 'e', the child process inherits a
192        copy of the environment block - ignoring the effects of putenv() and
193        [un]setenv().  */
194     {
195       child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
196                         (const char **) environ);
197       if (child < 0 && errno == ENOEXEC)
198         {
199           /* prog is not an native executable.  Try to execute it as a
200              shell script.  Note that prepare_spawn() has already prepended
201              a hidden element "sh.exe" to prog_argv.  */
202           --prog_argv;
203           child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
204                             (const char **) environ);
205         }
206     }
207   if (child == -1)
208     saved_errno = errno;
209   if (stdinfd >= 0)
210     close (stdinfd);
211   if (stdoutfd >= 0)
212     close (stdoutfd);
213   if (nulloutfd >= 0)
214     close (nulloutfd);
215
216   /* Restore standard file handles of parent process.  */
217   if (null_stderr)
218     undup_safer_noinherit (orig_stderr, STDERR_FILENO);
219   if (pipe_stdout || prog_stdout != NULL)
220     undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
221   if (pipe_stdin || prog_stdin != NULL)
222     undup_safer_noinherit (orig_stdin, STDIN_FILENO);
223
224   if (pipe_stdin)
225     close (ofd[0]);
226   if (pipe_stdout)
227     close (ifd[1]);
228   if (child == -1)
229     {
230       if (exit_on_error || !null_stderr)
231         error (exit_on_error ? EXIT_FAILURE : 0, saved_errno,
232                _("%s subprocess failed"), progname);
233       if (pipe_stdout)
234         close (ifd[0]);
235       if (pipe_stdin)
236         close (ofd[1]);
237       errno = saved_errno;
238       return -1;
239     }
240
241   if (pipe_stdout)
242     fd[0] = ifd[0];
243   if (pipe_stdin)
244     fd[1] = ofd[1];
245   return child;
246
247 #else
248
249   /* Unix API.  */
250   int ifd[2];
251   int ofd[2];
252   sigset_t blocked_signals;
253   posix_spawn_file_actions_t actions;
254   bool actions_allocated;
255   posix_spawnattr_t attrs;
256   bool attrs_allocated;
257   int err;
258   pid_t child;
259
260   if (pipe_stdout)
261     if (pipe_safer (ifd) < 0)
262       error (EXIT_FAILURE, errno, _("cannot create pipe"));
263   if (pipe_stdin)
264     if (pipe_safer (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 (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       errno = err;
358       return -1;
359     }
360   posix_spawn_file_actions_destroy (&actions);
361   if (attrs_allocated)
362     posix_spawnattr_destroy (&attrs);
363   if (slave_process)
364     {
365       register_slave_subprocess (child);
366       unblock_fatal_signals ();
367     }
368   if (pipe_stdin)
369     close (ofd[0]);
370   if (pipe_stdout)
371     close (ifd[1]);
372
373   if (pipe_stdout)
374     fd[0] = ifd[0];
375   if (pipe_stdin)
376     fd[1] = ofd[1];
377   return child;
378
379 #endif
380 }
381
382 /* Open a bidirectional pipe.
383  *
384  *           write       system                read
385  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child
386  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
387  *           read        system                write
388  *
389  */
390 pid_t
391 create_pipe_bidi (const char *progname,
392                   const char *prog_path, char **prog_argv,
393                   bool null_stderr,
394                   bool slave_process, bool exit_on_error,
395                   int fd[2])
396 {
397   pid_t result = create_pipe (progname, prog_path, prog_argv,
398                               true, true, NULL, NULL,
399                               null_stderr, slave_process, exit_on_error,
400                               fd);
401   return result;
402 }
403
404 /* Open a pipe for input from a child process.
405  * The child's stdin comes from a file.
406  *
407  *           read        system                write
408  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
409  *
410  */
411 pid_t
412 create_pipe_in (const char *progname,
413                 const char *prog_path, char **prog_argv,
414                 const char *prog_stdin, bool null_stderr,
415                 bool slave_process, bool exit_on_error,
416                 int fd[1])
417 {
418   int iofd[2];
419   pid_t result = create_pipe (progname, prog_path, prog_argv,
420                               false, true, prog_stdin, NULL,
421                               null_stderr, slave_process, exit_on_error,
422                               iofd);
423   if (result != -1)
424     fd[0] = iofd[0];
425   return result;
426 }
427
428 /* Open a pipe for output to a child process.
429  * The child's stdout goes to a file.
430  *
431  *           write       system                read
432  *    parent  ->   fd[0]   ->   STDIN_FILENO    ->   child
433  *
434  */
435 pid_t
436 create_pipe_out (const char *progname,
437                  const char *prog_path, char **prog_argv,
438                  const char *prog_stdout, bool null_stderr,
439                  bool slave_process, bool exit_on_error,
440                  int fd[1])
441 {
442   int iofd[2];
443   pid_t result = create_pipe (progname, prog_path, prog_argv,
444                               true, false, NULL, prog_stdout,
445                               null_stderr, slave_process, exit_on_error,
446                               iofd);
447   if (result != -1)
448     fd[0] = iofd[1];
449   return result;
450 }