1/* Creation of subprocesses, communicating via pipes.
2   Copyright (C) 2001-2004, 2006-2014 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 Windows 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
52#ifdef EINTR
53
54/* EINTR handling for close().
55   These functions can return -1/EINTR even though we don't have any
56   signal handlers set up, namely when we get interrupted via SIGSTOP.  */
57
58static int
59nonintr_close (int fd)
60{
61  int retval;
62
63  do
64    retval = close (fd);
65  while (retval < 0 && errno == EINTR);
66
67  return retval;
68}
69#define close nonintr_close
70
71#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
72static int
73nonintr_open (const char *pathname, int oflag, mode_t mode)
74{
75  int retval;
76
77  do
78    retval = open (pathname, oflag, mode);
79  while (retval < 0 && errno == EINTR);
80
81  return retval;
82}
83# undef open /* avoid warning on VMS */
84# define open nonintr_open
85#endif
86
87#endif
88
89
90/* Open a pipe connected to a child process.
91 *
92 *           write       system                read
93 *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child       if pipe_stdin
94 *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child       if pipe_stdout
95 *           read        system                write
96 *
97 * At least one of pipe_stdin, pipe_stdout must be true.
98 * pipe_stdin and prog_stdin together determine the child's standard input.
99 * pipe_stdout and prog_stdout together determine the child's standard output.
100 * If pipe_stdin is true, prog_stdin is ignored.
101 * If pipe_stdout is true, prog_stdout is ignored.
102 */
103static pid_t
104create_pipe (const char *progname,
105             const char *prog_path, char **prog_argv,
106             bool pipe_stdin, bool pipe_stdout,
107             const char *prog_stdin, const char *prog_stdout,
108             bool null_stderr,
109             bool slave_process, bool exit_on_error,
110             int fd[2])
111{
112#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
113
114  /* Native Windows API.
115     This uses _pipe(), dup2(), and spawnv().  It could also be implemented
116     using the low-level functions CreatePipe(), DuplicateHandle(),
117     CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
118     and cvs source code.  */
119  int ifd[2];
120  int ofd[2];
121  int orig_stdin;
122  int orig_stdout;
123  int orig_stderr;
124  int child;
125  int nulloutfd;
126  int stdinfd;
127  int stdoutfd;
128  int saved_errno;
129
130  /* FIXME: Need to free memory allocated by prepare_spawn.  */
131  prog_argv = prepare_spawn (prog_argv);
132
133  if (pipe_stdout)
134    if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
135      error (EXIT_FAILURE, errno, _("cannot create pipe"));
136  if (pipe_stdin)
137    if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
138      error (EXIT_FAILURE, errno, _("cannot create pipe"));
139/* Data flow diagram:
140 *
141 *           write        system         read
142 *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
143 *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
144 *           read         system         write
145 *
146 */
147
148  /* Save standard file handles of parent process.  */
149  if (pipe_stdin || prog_stdin != NULL)
150    orig_stdin = dup_safer_noinherit (STDIN_FILENO);
151  if (pipe_stdout || prog_stdout != NULL)
152    orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
153  if (null_stderr)
154    orig_stderr = dup_safer_noinherit (STDERR_FILENO);
155  child = -1;
156
157  /* Create standard file handles of child process.  */
158  nulloutfd = -1;
159  stdinfd = -1;
160  stdoutfd = -1;
161  if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
162      && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
163      && (!null_stderr
164          || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
165              && (nulloutfd == STDERR_FILENO
166                  || (dup2 (nulloutfd, STDERR_FILENO) >= 0
167                      && close (nulloutfd) >= 0))))
168      && (pipe_stdin
169          || prog_stdin == NULL
170          || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
171              && (stdinfd == STDIN_FILENO
172                  || (dup2 (stdinfd, STDIN_FILENO) >= 0
173                      && close (stdinfd) >= 0))))
174      && (pipe_stdout
175          || prog_stdout == NULL
176          || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
177              && (stdoutfd == STDOUT_FILENO
178                  || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
179                      && close (stdoutfd) >= 0)))))
180    /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
181       but it inherits all open()ed or dup2()ed file handles (which is what
182       we want in the case of STD*_FILENO).  */
183    /* Use spawnvpe and pass the environment explicitly.  This is needed if
184       the program has modified the environment using putenv() or [un]setenv().
185       On Windows, programs have two environments, one in the "environment
186       block" of the process and managed through SetEnvironmentVariable(), and
187       one inside the process, in the location retrieved by the 'environ'
188       macro.  When using spawnvp() without 'e', the child process inherits a
189       copy of the environment block - ignoring the effects of putenv() and
190       [un]setenv().  */
191    {
192      child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
193                        (const char **) environ);
194      if (child < 0 && errno == ENOEXEC)
195        {
196          /* prog is not a native executable.  Try to execute it as a
197             shell script.  Note that prepare_spawn() has already prepended
198             a hidden element "sh.exe" to prog_argv.  */
199          --prog_argv;
200          child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
201                            (const char **) environ);
202        }
203    }
204  if (child == -1)
205    saved_errno = errno;
206  if (stdinfd >= 0)
207    close (stdinfd);
208  if (stdoutfd >= 0)
209    close (stdoutfd);
210  if (nulloutfd >= 0)
211    close (nulloutfd);
212
213  /* Restore standard file handles of parent process.  */
214  if (null_stderr)
215    undup_safer_noinherit (orig_stderr, STDERR_FILENO);
216  if (pipe_stdout || prog_stdout != NULL)
217    undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
218  if (pipe_stdin || prog_stdin != NULL)
219    undup_safer_noinherit (orig_stdin, STDIN_FILENO);
220
221  if (pipe_stdin)
222    close (ofd[0]);
223  if (pipe_stdout)
224    close (ifd[1]);
225  if (child == -1)
226    {
227      if (exit_on_error || !null_stderr)
228        error (exit_on_error ? EXIT_FAILURE : 0, saved_errno,
229               _("%s subprocess failed"), progname);
230      if (pipe_stdout)
231        close (ifd[0]);
232      if (pipe_stdin)
233        close (ofd[1]);
234      errno = saved_errno;
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  sigset_t blocked_signals;
250  posix_spawn_file_actions_t actions;
251  bool actions_allocated;
252  posix_spawnattr_t attrs;
253  bool attrs_allocated;
254  int err;
255  pid_t child;
256
257  if (pipe_stdout)
258    if (pipe_safer (ifd) < 0)
259      error (EXIT_FAILURE, errno, _("cannot create pipe"));
260  if (pipe_stdin)
261    if (pipe_safer (ofd) < 0)
262      error (EXIT_FAILURE, errno, _("cannot create pipe"));
263/* Data flow diagram:
264 *
265 *           write        system         read
266 *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
267 *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
268 *           read         system         write
269 *
270 */
271
272  if (slave_process)
273    {
274      sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
275      block_fatal_signals ();
276    }
277  actions_allocated = false;
278  attrs_allocated = false;
279  if ((err = posix_spawn_file_actions_init (&actions)) != 0
280      || (actions_allocated = true,
281          (pipe_stdin
282           && (err = posix_spawn_file_actions_adddup2 (&actions,
283                                                       ofd[0], STDIN_FILENO))
284              != 0)
285          || (pipe_stdout
286              && (err = posix_spawn_file_actions_adddup2 (&actions,
287                                                          ifd[1], STDOUT_FILENO))
288                 != 0)
289          || (pipe_stdin
290              && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
291                 != 0)
292          || (pipe_stdout
293              && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
294                 != 0)
295          || (pipe_stdin
296              && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
297                 != 0)
298          || (pipe_stdout
299              && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
300                 != 0)
301          || (null_stderr
302              && (err = posix_spawn_file_actions_addopen (&actions,
303                                                          STDERR_FILENO,
304                                                          "/dev/null", O_RDWR,
305                                                          0))
306                 != 0)
307          || (!pipe_stdin
308              && prog_stdin != NULL
309              && (err = posix_spawn_file_actions_addopen (&actions,
310                                                          STDIN_FILENO,
311                                                          prog_stdin, O_RDONLY,
312                                                          0))
313                 != 0)
314          || (!pipe_stdout
315              && prog_stdout != NULL
316              && (err = posix_spawn_file_actions_addopen (&actions,
317                                                          STDOUT_FILENO,
318                                                          prog_stdout, O_WRONLY,
319                                                          0))
320                 != 0)
321          || (slave_process
322              && ((err = posix_spawnattr_init (&attrs)) != 0
323                  || (attrs_allocated = true,
324                      (err = posix_spawnattr_setsigmask (&attrs,
325                                                         &blocked_signals))
326                      != 0
327                      || (err = posix_spawnattr_setflags (&attrs,
328                                                        POSIX_SPAWN_SETSIGMASK))
329                         != 0)))
330          || (err = posix_spawnp (&child, prog_path, &actions,
331                                  attrs_allocated ? &attrs : NULL, prog_argv,
332                                  environ))
333             != 0))
334    {
335      if (actions_allocated)
336        posix_spawn_file_actions_destroy (&actions);
337      if (attrs_allocated)
338        posix_spawnattr_destroy (&attrs);
339      if (slave_process)
340        unblock_fatal_signals ();
341      if (exit_on_error || !null_stderr)
342        error (exit_on_error ? EXIT_FAILURE : 0, err,
343               _("%s subprocess failed"), progname);
344      if (pipe_stdout)
345        {
346          close (ifd[0]);
347          close (ifd[1]);
348        }
349      if (pipe_stdin)
350        {
351          close (ofd[0]);
352          close (ofd[1]);
353        }
354      errno = err;
355      return -1;
356    }
357  posix_spawn_file_actions_destroy (&actions);
358  if (attrs_allocated)
359    posix_spawnattr_destroy (&attrs);
360  if (slave_process)
361    {
362      register_slave_subprocess (child);
363      unblock_fatal_signals ();
364    }
365  if (pipe_stdin)
366    close (ofd[0]);
367  if (pipe_stdout)
368    close (ifd[1]);
369
370  if (pipe_stdout)
371    fd[0] = ifd[0];
372  if (pipe_stdin)
373    fd[1] = ofd[1];
374  return child;
375
376#endif
377}
378
379/* Open a bidirectional pipe.
380 *
381 *           write       system                read
382 *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child
383 *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
384 *           read        system                write
385 *
386 */
387pid_t
388create_pipe_bidi (const char *progname,
389                  const char *prog_path, char **prog_argv,
390                  bool null_stderr,
391                  bool slave_process, bool exit_on_error,
392                  int fd[2])
393{
394  pid_t result = create_pipe (progname, prog_path, prog_argv,
395                              true, true, NULL, NULL,
396                              null_stderr, slave_process, exit_on_error,
397                              fd);
398  return result;
399}
400
401/* Open a pipe for input from a child process.
402 * The child's stdin comes from a file.
403 *
404 *           read        system                write
405 *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child
406 *
407 */
408pid_t
409create_pipe_in (const char *progname,
410                const char *prog_path, char **prog_argv,
411                const char *prog_stdin, bool null_stderr,
412                bool slave_process, bool exit_on_error,
413                int fd[1])
414{
415  int iofd[2];
416  pid_t result = create_pipe (progname, prog_path, prog_argv,
417                              false, true, prog_stdin, NULL,
418                              null_stderr, slave_process, exit_on_error,
419                              iofd);
420  if (result != -1)
421    fd[0] = iofd[0];
422  return result;
423}
424
425/* Open a pipe for output to a child process.
426 * The child's stdout goes to a file.
427 *
428 *           write       system                read
429 *    parent  ->   fd[0]   ->   STDIN_FILENO    ->   child
430 *
431 */
432pid_t
433create_pipe_out (const char *progname,
434                 const char *prog_path, char **prog_argv,
435                 const char *prog_stdout, bool null_stderr,
436                 bool slave_process, bool exit_on_error,
437                 int fd[1])
438{
439  int iofd[2];
440  pid_t result = create_pipe (progname, prog_path, prog_argv,
441                              true, false, NULL, prog_stdout,
442                              null_stderr, slave_process, exit_on_error,
443                              iofd);
444  if (result != -1)
445    fd[0] = iofd[1];
446  return result;
447}
448