1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
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.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19 /* Tell clang not to warn about the 'child' variable, below. */
21 # pragma clang diagnostic ignored "-Wconditional-uninitialized"
27 #include "spawn-pipe.h"
35 #include "canonicalize.h"
37 #include "fatal-signal.h"
40 #include "unistd-safer.h"
41 #include "wait-process.h"
44 #define _(str) gettext (str)
46 #if defined _WIN32 && ! defined __CYGWIN__
48 /* Native Windows API. */
49 # if GNULIB_MSVC_NOTHROW
50 # include "msvc-nothrow.h"
55 # include "windows-spawn.h"
57 #elif defined __KLIBC__
61 # include "os2-spawn.h"
73 /* EINTR handling for close().
74 These functions can return -1/EINTR even though we don't have any
75 signal handlers set up, namely when we get interrupted via SIGSTOP. */
78 nonintr_close (int fd
)
84 while (retval
< 0 && errno
== EINTR
);
88 #undef close /* avoid warning related to gnulib module unistd */
89 #define close nonintr_close
91 #if defined _WIN32 && ! defined __CYGWIN__
93 nonintr_open (const char *pathname
, int oflag
, mode_t mode
)
98 retval
= open (pathname
, oflag
, mode
);
99 while (retval
< 0 && errno
== EINTR
);
103 # undef open /* avoid warning on VMS */
104 # define open nonintr_open
110 /* Open a pipe connected to a child process.
113 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
114 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
117 * At least one of pipe_stdin, pipe_stdout must be true.
118 * pipe_stdin and prog_stdin together determine the child's standard input.
119 * pipe_stdout and prog_stdout together determine the child's standard output.
120 * If pipe_stdin is true, prog_stdin is ignored.
121 * If pipe_stdout is true, prog_stdout is ignored.
124 create_pipe (const char *progname
,
125 const char *prog_path
, char **prog_argv
,
126 const char *directory
,
127 bool pipe_stdin
, bool pipe_stdout
,
128 const char *prog_stdin
, const char *prog_stdout
,
130 bool slave_process
, bool exit_on_error
,
134 char *prog_path_to_free
= NULL
;
136 if (directory
!= NULL
)
138 /* If a change of directory is requested, make sure PROG_PATH is absolute
139 before we do so. This is needed because
140 - posix_spawn and posix_spawnp are required to resolve a relative
141 PROG_PATH *after* changing the directory. See
142 <https://www.austingroupbugs.net/view.php?id=1208>:
143 "if this pathname does not start with a <slash> it shall be
144 interpreted relative to the working directory of the child
145 process _after_ all file_actions have been performed."
146 But this would be a surprising application behaviour, possibly
147 even security relevant.
148 - For the Windows CreateProcess() function, it is unspecified whether
149 a relative file name is interpreted to the parent's current
150 directory or to the specified directory. See
151 <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa> */
152 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
154 const char *resolved_prog
=
155 find_in_given_path (prog_path
, getenv ("PATH"), false);
156 if (resolved_prog
== NULL
)
157 goto fail_with_errno
;
158 if (resolved_prog
!= prog_path
)
159 prog_path_to_free
= (char *) resolved_prog
;
160 prog_path
= resolved_prog
;
162 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
164 char *absolute_prog
=
165 canonicalize_filename_mode (prog_path
, CAN_MISSING
| CAN_NOLINKS
);
166 if (absolute_prog
== NULL
)
169 free (prog_path_to_free
);
170 goto fail_with_saved_errno
;
172 free (prog_path_to_free
);
173 prog_path_to_free
= absolute_prog
;
174 prog_path
= absolute_prog
;
176 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
182 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
184 /* Native Windows API.
185 This uses _pipe(), dup2(), and _spawnv(). It could also be implemented
186 using the low-level functions CreatePipe(), DuplicateHandle(),
187 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
188 and cvs source code. */
196 /* FIXME: Need to free memory allocated by prepare_spawn. */
197 prog_argv
= prepare_spawn (prog_argv
);
200 if (pipe2_safer (ifd
, O_BINARY
| O_CLOEXEC
) < 0)
201 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
203 if (pipe2_safer (ofd
, O_BINARY
| O_CLOEXEC
) < 0)
204 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
205 /* Data flow diagram:
208 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
209 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
216 # if defined _WIN32 && ! defined __CYGWIN__
217 bool must_close_ifd1
= pipe_stdout
;
218 bool must_close_ofd0
= pipe_stdin
;
220 /* Create standard file handles of child process. */
225 || (nulloutfd
= open ("NUL", O_RDWR
, 0)) >= 0)
227 || prog_stdin
== NULL
228 || (stdinfd
= open (prog_stdin
, O_RDONLY
, 0)) >= 0)
230 || prog_stdout
== NULL
231 || (stdoutfd
= open (prog_stdout
, O_WRONLY
, 0)) >= 0))
232 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
233 but it inherits the three STD*_FILENO for which we pass the handles. */
234 /* Pass the environment explicitly. This is needed if the program has
235 modified the environment using putenv() or [un]setenv(). On Windows,
236 processes have two environments, one in the "environment block" of the
237 process and managed through SetEnvironmentVariable(), and one inside the
238 process, in the location retrieved by the 'environ' macro. If we were
239 to pass NULL, the child process would inherit a copy of the environment
240 block - ignoring the effects of putenv() and [un]setenv(). */
242 HANDLE stdin_handle
=
243 (HANDLE
) _get_osfhandle (pipe_stdin
? ofd
[0] :
244 prog_stdin
== NULL
? STDIN_FILENO
: stdinfd
);
247 HANDLE curr_process
= GetCurrentProcess ();
249 if (!DuplicateHandle (curr_process
, stdin_handle
,
250 curr_process
, &duplicate
,
251 0, TRUE
, DUPLICATE_SAME_ACCESS
))
253 errno
= EBADF
; /* arbitrary */
256 must_close_ofd0
= false;
257 close (ofd
[0]); /* implies CloseHandle (stdin_handle); */
258 stdin_handle
= duplicate
;
260 HANDLE stdout_handle
=
261 (HANDLE
) _get_osfhandle (pipe_stdout
? ifd
[1] :
262 prog_stdout
== NULL
? STDOUT_FILENO
: stdoutfd
);
265 HANDLE curr_process
= GetCurrentProcess ();
267 if (!DuplicateHandle (curr_process
, stdout_handle
,
268 curr_process
, &duplicate
,
269 0, TRUE
, DUPLICATE_SAME_ACCESS
))
271 errno
= EBADF
; /* arbitrary */
274 must_close_ifd1
= false;
275 close (ifd
[1]); /* implies CloseHandle (stdout_handle); */
276 stdout_handle
= duplicate
;
278 HANDLE stderr_handle
=
279 (HANDLE
) _get_osfhandle (null_stderr
? nulloutfd
: STDERR_FILENO
);
281 child
= spawnpvech (P_NOWAIT
, prog_path
, (const char **) prog_argv
,
282 (const char **) environ
, directory
,
283 stdin_handle
, stdout_handle
, stderr_handle
);
284 if (child
== -1 && errno
== ENOEXEC
)
286 /* prog is not a native executable. Try to execute it as a
287 shell script. Note that prepare_spawn() has already prepended
288 a hidden element "sh.exe" to prog_argv. */
289 prog_argv
[0] = prog_path
;
291 child
= spawnpvech (P_NOWAIT
, prog_argv
[0], (const char **) prog_argv
,
292 (const char **) environ
, directory
,
293 stdin_handle
, stdout_handle
, stderr_handle
);
311 # else /* __KLIBC__ */
312 if (!(directory
== NULL
&& strcmp (directory
, ".") == 0))
314 /* A directory argument is not supported in this implementation. */
315 saved_errno
= EINVAL
;
316 goto fail_with_saved_errno
;
323 /* Save standard file handles of parent process. */
324 if (pipe_stdin
|| prog_stdin
!= NULL
)
325 orig_stdin
= dup_safer_noinherit (STDIN_FILENO
);
326 if (pipe_stdout
|| prog_stdout
!= NULL
)
327 orig_stdout
= dup_safer_noinherit (STDOUT_FILENO
);
329 orig_stderr
= dup_safer_noinherit (STDERR_FILENO
);
331 /* Create standard file handles of child process. */
335 if ((!pipe_stdin
|| dup2 (ofd
[0], STDIN_FILENO
) >= 0)
336 && (!pipe_stdout
|| dup2 (ifd
[1], STDOUT_FILENO
) >= 0)
338 || ((nulloutfd
= open ("NUL", O_RDWR
, 0)) >= 0
339 && (nulloutfd
== STDERR_FILENO
340 || (dup2 (nulloutfd
, STDERR_FILENO
) >= 0
341 && close (nulloutfd
) >= 0))))
343 || prog_stdin
== NULL
344 || ((stdinfd
= open (prog_stdin
, O_RDONLY
, 0)) >= 0
345 && (stdinfd
== STDIN_FILENO
346 || (dup2 (stdinfd
, STDIN_FILENO
) >= 0
347 && close (stdinfd
) >= 0))))
349 || prog_stdout
== NULL
350 || ((stdoutfd
= open (prog_stdout
, O_WRONLY
, 0)) >= 0
351 && (stdoutfd
== STDOUT_FILENO
352 || (dup2 (stdoutfd
, STDOUT_FILENO
) >= 0
353 && close (stdoutfd
) >= 0)))))
354 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
355 but it inherits all open()ed or dup2()ed file handles (which is what
356 we want in the case of STD*_FILENO). */
358 child
= _spawnvpe (P_NOWAIT
, prog_path
, (const char **) prog_argv
,
359 (const char **) environ
);
360 if (child
== -1 && errno
== ENOEXEC
)
362 /* prog is not a native executable. Try to execute it as a
363 shell script. Note that prepare_spawn() has already prepended
364 a hidden element "sh.exe" to prog_argv. */
366 child
= _spawnvpe (P_NOWAIT
, prog_argv
[0], (const char **) prog_argv
,
367 (const char **) environ
);
379 /* Restore standard file handles of parent process. */
381 undup_safer_noinherit (orig_stderr
, STDERR_FILENO
);
382 if (pipe_stdout
|| prog_stdout
!= NULL
)
383 undup_safer_noinherit (orig_stdout
, STDOUT_FILENO
);
384 if (pipe_stdin
|| prog_stdin
!= NULL
)
385 undup_safer_noinherit (orig_stdin
, STDIN_FILENO
);
393 free (prog_path_to_free
);
401 goto fail_with_saved_errno
;
415 sigset_t blocked_signals
;
416 posix_spawn_file_actions_t actions
;
417 bool actions_allocated
;
418 posix_spawnattr_t attrs
;
419 bool attrs_allocated
;
424 if (pipe_safer (ifd
) < 0)
425 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
427 if (pipe_safer (ofd
) < 0)
428 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
429 /* Data flow diagram:
432 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
433 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
440 sigprocmask (SIG_SETMASK
, NULL
, &blocked_signals
);
441 block_fatal_signals ();
443 actions_allocated
= false;
444 attrs_allocated
= false;
445 if ((err
= posix_spawn_file_actions_init (&actions
)) != 0
446 || (actions_allocated
= true,
448 && (err
= posix_spawn_file_actions_adddup2 (&actions
,
449 ofd
[0], STDIN_FILENO
))
452 && (err
= posix_spawn_file_actions_adddup2 (&actions
,
453 ifd
[1], STDOUT_FILENO
))
456 && (err
= posix_spawn_file_actions_addclose (&actions
, ofd
[0]))
459 && (err
= posix_spawn_file_actions_addclose (&actions
, ifd
[1]))
462 && (err
= posix_spawn_file_actions_addclose (&actions
, ofd
[1]))
465 && (err
= posix_spawn_file_actions_addclose (&actions
, ifd
[0]))
468 && (err
= posix_spawn_file_actions_addopen (&actions
,
474 && prog_stdin
!= NULL
475 && (err
= posix_spawn_file_actions_addopen (&actions
,
477 prog_stdin
, O_RDONLY
,
481 && prog_stdout
!= NULL
482 && (err
= posix_spawn_file_actions_addopen (&actions
,
484 prog_stdout
, O_WRONLY
,
487 || (directory
!= NULL
488 && (err
= posix_spawn_file_actions_addchdir (&actions
,
491 && ((err
= posix_spawnattr_init (&attrs
)) != 0
492 || (attrs_allocated
= true,
493 (err
= posix_spawnattr_setsigmask (&attrs
,
496 || (err
= posix_spawnattr_setflags (&attrs
,
497 POSIX_SPAWN_SETSIGMASK
))
499 || (err
= (directory
!= NULL
500 ? posix_spawn (&child
, prog_path
, &actions
,
501 attrs_allocated
? &attrs
: NULL
, prog_argv
,
503 : posix_spawnp (&child
, prog_path
, &actions
,
504 attrs_allocated
? &attrs
: NULL
, prog_argv
,
508 if (actions_allocated
)
509 posix_spawn_file_actions_destroy (&actions
);
511 posix_spawnattr_destroy (&attrs
);
513 unblock_fatal_signals ();
524 free (prog_path_to_free
);
526 goto fail_with_saved_errno
;
528 posix_spawn_file_actions_destroy (&actions
);
530 posix_spawnattr_destroy (&attrs
);
533 register_slave_subprocess (child
);
534 unblock_fatal_signals ();
540 free (prog_path_to_free
);
552 fail_with_saved_errno
:
553 if (exit_on_error
|| !null_stderr
)
554 error (exit_on_error
? EXIT_FAILURE
: 0, saved_errno
,
555 _("%s subprocess failed"), progname
);
560 /* Open a bidirectional pipe.
563 * parent -> fd[1] -> STDIN_FILENO -> child
564 * parent <- fd[0] <- STDOUT_FILENO <- child
569 create_pipe_bidi (const char *progname
,
570 const char *prog_path
, char **prog_argv
,
571 const char *directory
,
573 bool slave_process
, bool exit_on_error
,
576 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
577 true, true, NULL
, NULL
,
578 null_stderr
, slave_process
, exit_on_error
,
583 /* Open a pipe for input from a child process.
584 * The child's stdin comes from a file.
587 * parent <- fd[0] <- STDOUT_FILENO <- child
591 create_pipe_in (const char *progname
,
592 const char *prog_path
, char **prog_argv
,
593 const char *directory
,
594 const char *prog_stdin
, bool null_stderr
,
595 bool slave_process
, bool exit_on_error
,
599 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
600 false, true, prog_stdin
, NULL
,
601 null_stderr
, slave_process
, exit_on_error
,
608 /* Open a pipe for output to a child process.
609 * The child's stdout goes to a file.
612 * parent -> fd[0] -> STDIN_FILENO -> child
616 create_pipe_out (const char *progname
,
617 const char *prog_path
, char **prog_argv
,
618 const char *directory
,
619 const char *prog_stdout
, bool null_stderr
,
620 bool slave_process
, bool exit_on_error
,
624 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
625 true, false, NULL
, prog_stdout
,
626 null_stderr
, slave_process
, exit_on_error
,