Bump to 1.14.1
[platform/upstream/augeas.git] / lib / spawn-pipe.c
1 /* Creation of subprocesses, communicating via pipes.
2    Copyright (C) 2001-2004, 2006-2016 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      || defined __KLIBC__)
40
41 /* Native Windows API.  */
42 # include <process.h>
43 # include "w32spawn.h"
44
45 #else
46
47 /* Unix API.  */
48 # include <spawn.h>
49
50 #endif
51
52
53 #ifdef EINTR
54
55 /* EINTR handling for close().
56    These functions can return -1/EINTR even though we don't have any
57    signal handlers set up, namely when we get interrupted via SIGSTOP.  */
58
59 static int
60 nonintr_close (int fd)
61 {
62   int retval;
63
64   do
65     retval = close (fd);
66   while (retval < 0 && errno == EINTR);
67
68   return retval;
69 }
70 #define close nonintr_close
71
72 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
73 static int
74 nonintr_open (const char *pathname, int oflag, mode_t mode)
75 {
76   int retval;
77
78   do
79     retval = open (pathname, oflag, mode);
80   while (retval < 0 && errno == EINTR);
81
82   return retval;
83 }
84 # undef open /* avoid warning on VMS */
85 # define open nonintr_open
86 #endif
87
88 #endif
89
90
91 /* Open a pipe connected to a child process.
92  *
93  *           write       system                read
94  *    parent  ->   fd[1]   ->   STDIN_FILENO    ->   child       if pipe_stdin
95  *    parent  <-   fd[0]   <-   STDOUT_FILENO   <-   child       if pipe_stdout
96  *           read        system                write
97  *
98  * At least one of pipe_stdin, pipe_stdout must be true.
99  * pipe_stdin and prog_stdin together determine the child's standard input.
100  * pipe_stdout and prog_stdout together determine the child's standard output.
101  * If pipe_stdin is true, prog_stdin is ignored.
102  * If pipe_stdout is true, prog_stdout is ignored.
103  */
104 static pid_t
105 create_pipe (const char *progname,
106              const char *prog_path, char **prog_argv,
107              bool pipe_stdin, bool pipe_stdout,
108              const char *prog_stdin, const char *prog_stdout,
109              bool null_stderr,
110              bool slave_process, bool exit_on_error,
111              int fd[2])
112 {
113 #if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
114      || defined __KLIBC__)
115
116   /* Native Windows API.
117      This uses _pipe(), dup2(), and spawnv().  It could also be implemented
118      using the low-level functions CreatePipe(), DuplicateHandle(),
119      CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
120      and cvs source code.  */
121   int ifd[2];
122   int ofd[2];
123   int orig_stdin;
124   int orig_stdout;
125   int orig_stderr;
126   int child;
127   int nulloutfd;
128   int stdinfd;
129   int stdoutfd;
130   int saved_errno;
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 (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
137       error (EXIT_FAILURE, errno, _("cannot create pipe"));
138   if (pipe_stdin)
139     if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
140       error (EXIT_FAILURE, errno, _("cannot create pipe"));
141 /* Data flow diagram:
142  *
143  *           write        system         read
144  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
145  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
146  *           read         system         write
147  *
148  */
149
150   /* Save standard file handles of parent process.  */
151   if (pipe_stdin || prog_stdin != NULL)
152     orig_stdin = dup_safer_noinherit (STDIN_FILENO);
153   if (pipe_stdout || prog_stdout != NULL)
154     orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
155   if (null_stderr)
156     orig_stderr = dup_safer_noinherit (STDERR_FILENO);
157   child = -1;
158
159   /* Create standard file handles of child process.  */
160   nulloutfd = -1;
161   stdinfd = -1;
162   stdoutfd = -1;
163   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
164       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
165       && (!null_stderr
166           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
167               && (nulloutfd == STDERR_FILENO
168                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
169                       && close (nulloutfd) >= 0))))
170       && (pipe_stdin
171           || prog_stdin == NULL
172           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
173               && (stdinfd == STDIN_FILENO
174                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
175                       && close (stdinfd) >= 0))))
176       && (pipe_stdout
177           || prog_stdout == NULL
178           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
179               && (stdoutfd == STDOUT_FILENO
180                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
181                       && close (stdoutfd) >= 0)))))
182     /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
183        but it inherits all open()ed or dup2()ed file handles (which is what
184        we want in the case of STD*_FILENO).  */
185     /* Use spawnvpe and pass the environment explicitly.  This is needed if
186        the program has modified the environment using putenv() or [un]setenv().
187        On Windows, programs have two environments, one in the "environment
188        block" of the process and managed through SetEnvironmentVariable(), and
189        one inside the process, in the location retrieved by the 'environ'
190        macro.  When using spawnvp() without 'e', the child process inherits a
191        copy of the environment block - ignoring the effects of putenv() and
192        [un]setenv().  */
193     {
194       child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
195                         (const char **) environ);
196       if (child < 0 && errno == ENOEXEC)
197         {
198           /* prog is not a native executable.  Try to execute it as a
199              shell script.  Note that prepare_spawn() has already prepended
200              a hidden element "sh.exe" to prog_argv.  */
201           --prog_argv;
202           child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
203                             (const char **) environ);
204         }
205     }
206   if (child == -1)
207     saved_errno = errno;
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     undup_safer_noinherit (orig_stderr, STDERR_FILENO);
218   if (pipe_stdout || prog_stdout != NULL)
219     undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
220   if (pipe_stdin || prog_stdin != NULL)
221     undup_safer_noinherit (orig_stdin, STDIN_FILENO);
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, saved_errno,
231                _("%s subprocess failed"), progname);
232       if (pipe_stdout)
233         close (ifd[0]);
234       if (pipe_stdin)
235         close (ofd[1]);
236       errno = saved_errno;
237       return -1;
238     }
239
240   if (pipe_stdout)
241     fd[0] = ifd[0];
242   if (pipe_stdin)
243     fd[1] = ofd[1];
244   return child;
245
246 #else
247
248   /* Unix API.  */
249   int ifd[2];
250   int ofd[2];
251   sigset_t blocked_signals;
252   posix_spawn_file_actions_t actions;
253   bool actions_allocated;
254   posix_spawnattr_t attrs;
255   bool attrs_allocated;
256   int err;
257   pid_t child;
258
259   if (pipe_stdout)
260     if (pipe_safer (ifd) < 0)
261       error (EXIT_FAILURE, errno, _("cannot create pipe"));
262   if (pipe_stdin)
263     if (pipe_safer (ofd) < 0)
264       error (EXIT_FAILURE, errno, _("cannot create pipe"));
265 /* Data flow diagram:
266  *
267  *           write        system         read
268  *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
269  *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
270  *           read         system         write
271  *
272  */
273
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       errno = err;
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 }