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