1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006-2021 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"
45 #define _(str) gettext (str)
48 /* Choice of implementation for native Windows.
49 - Define to 0 to use the posix_spawn facility (modules 'posix_spawn' and
50 'posix_spawnp'), that is based on the module 'windows-spawn'.
51 - Define to 1 to use the older code, that uses the module 'windows-spawn'
53 You can set this macro from a Makefile or at configure time, from the
55 #ifndef SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
56 # define SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN 0
60 #if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
62 /* Native Windows API. */
63 # if GNULIB_MSVC_NOTHROW
64 # include "msvc-nothrow.h"
69 # include "windows-spawn.h"
71 #elif defined __KLIBC__
75 # include "os2-spawn.h"
87 /* EINTR handling for close().
88 These functions can return -1/EINTR even though we don't have any
89 signal handlers set up, namely when we get interrupted via SIGSTOP. */
92 nonintr_close (int fd
)
98 while (retval
< 0 && errno
== EINTR
);
102 #undef close /* avoid warning related to gnulib module unistd */
103 #define close nonintr_close
105 #if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
107 nonintr_open (const char *pathname
, int oflag
, mode_t mode
)
112 retval
= open (pathname
, oflag
, mode
);
113 while (retval
< 0 && errno
== EINTR
);
117 # undef open /* avoid warning on VMS */
118 # define open nonintr_open
124 /* Open a pipe connected to a child process.
127 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
128 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
131 * At least one of pipe_stdin, pipe_stdout must be true.
132 * pipe_stdin and prog_stdin together determine the child's standard input.
133 * pipe_stdout and prog_stdout together determine the child's standard output.
134 * If pipe_stdin is true, prog_stdin is ignored.
135 * If pipe_stdout is true, prog_stdout is ignored.
138 create_pipe (const char *progname
,
139 const char *prog_path
,
140 const char * const *prog_argv
,
141 const char *directory
,
142 bool pipe_stdin
, bool pipe_stdout
,
143 const char *prog_stdin
, const char *prog_stdout
,
145 bool slave_process
, bool exit_on_error
,
149 char *prog_path_to_free
= NULL
;
151 if (directory
!= NULL
)
153 /* If a change of directory is requested, make sure PROG_PATH is absolute
154 before we do so. This is needed because
155 - posix_spawn and posix_spawnp are required to resolve a relative
156 PROG_PATH *after* changing the directory. See
157 <https://www.austingroupbugs.net/view.php?id=1208>:
158 "if this pathname does not start with a <slash> it shall be
159 interpreted relative to the working directory of the child
160 process _after_ all file_actions have been performed."
161 But this would be a surprising application behaviour, possibly
162 even security relevant.
163 - For the Windows CreateProcess() function, it is unspecified whether
164 a relative file name is interpreted to the parent's current
165 directory or to the specified directory. See
166 <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa> */
167 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
169 const char *resolved_prog
=
170 find_in_given_path (prog_path
, getenv ("PATH"), NULL
, false);
171 if (resolved_prog
== NULL
)
172 goto fail_with_errno
;
173 if (resolved_prog
!= prog_path
)
174 prog_path_to_free
= (char *) resolved_prog
;
175 prog_path
= resolved_prog
;
177 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
179 char *absolute_prog
=
180 canonicalize_filename_mode (prog_path
, CAN_MISSING
| CAN_NOLINKS
);
181 if (absolute_prog
== NULL
)
184 free (prog_path_to_free
);
185 goto fail_with_saved_errno
;
187 free (prog_path_to_free
);
188 prog_path_to_free
= absolute_prog
;
189 prog_path
= absolute_prog
;
191 if (! IS_ABSOLUTE_FILE_NAME (prog_path
))
197 #if ((defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN) || defined __KLIBC__
199 /* Native Windows API.
200 This uses _pipe(), dup2(), and _spawnv(). It could also be implemented
201 using the low-level functions CreatePipe(), DuplicateHandle(),
202 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
203 and cvs source code. */
204 char *argv_mem_to_free
;
212 const char **argv
= prepare_spawn (prog_argv
, &argv_mem_to_free
);
217 if (pipe2_safer (ifd
, O_BINARY
| O_CLOEXEC
) < 0)
218 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
220 if (pipe2_safer (ofd
, O_BINARY
| O_CLOEXEC
) < 0)
221 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
222 /* Data flow diagram:
225 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
226 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
233 # if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
234 bool must_close_ifd1
= pipe_stdout
;
235 bool must_close_ofd0
= pipe_stdin
;
237 /* Create standard file handles of child process. */
238 HANDLE stdin_handle
= INVALID_HANDLE_VALUE
;
239 HANDLE stdout_handle
= INVALID_HANDLE_VALUE
;
244 || (nulloutfd
= open ("NUL", O_RDWR
, 0)) >= 0)
246 || prog_stdin
== NULL
247 || (stdinfd
= open (prog_stdin
, O_RDONLY
, 0)) >= 0)
249 || prog_stdout
== NULL
250 || (stdoutfd
= open (prog_stdout
, O_WRONLY
, 0)) >= 0))
251 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
252 but it inherits the three STD*_FILENO for which we pass the handles. */
253 /* Pass the environment explicitly. This is needed if the program has
254 modified the environment using putenv() or [un]setenv(). On Windows,
255 processes have two environments, one in the "environment block" of the
256 process and managed through SetEnvironmentVariable(), and one inside the
257 process, in the location retrieved by the 'environ' macro. If we were
258 to pass NULL, the child process would inherit a copy of the environment
259 block - ignoring the effects of putenv() and [un]setenv(). */
262 (HANDLE
) _get_osfhandle (pipe_stdin
? ofd
[0] :
263 prog_stdin
== NULL
? STDIN_FILENO
: stdinfd
);
266 HANDLE curr_process
= GetCurrentProcess ();
268 if (!DuplicateHandle (curr_process
, stdin_handle
,
269 curr_process
, &duplicate
,
270 0, TRUE
, DUPLICATE_SAME_ACCESS
))
272 errno
= EBADF
; /* arbitrary */
275 must_close_ofd0
= false;
276 close (ofd
[0]); /* implies CloseHandle (stdin_handle); */
277 stdin_handle
= duplicate
;
280 (HANDLE
) _get_osfhandle (pipe_stdout
? ifd
[1] :
281 prog_stdout
== NULL
? STDOUT_FILENO
: stdoutfd
);
284 HANDLE curr_process
= GetCurrentProcess ();
286 if (!DuplicateHandle (curr_process
, stdout_handle
,
287 curr_process
, &duplicate
,
288 0, TRUE
, DUPLICATE_SAME_ACCESS
))
290 errno
= EBADF
; /* arbitrary */
293 must_close_ifd1
= false;
294 close (ifd
[1]); /* implies CloseHandle (stdout_handle); */
295 stdout_handle
= duplicate
;
297 HANDLE stderr_handle
=
298 (HANDLE
) _get_osfhandle (null_stderr
? nulloutfd
: STDERR_FILENO
);
300 child
= spawnpvech (P_NOWAIT
, prog_path
, argv
+ 1,
301 (const char * const *) environ
, directory
,
302 stdin_handle
, stdout_handle
, stderr_handle
);
303 # if 0 /* Executing arbitrary files as shell scripts is unsecure. */
304 if (child
== -1 && errno
== ENOEXEC
)
306 /* prog is not a native executable. Try to execute it as a
307 shell script. Note that prepare_spawn() has already prepended
308 a hidden element "sh.exe" to argv. */
310 child
= spawnpvech (P_NOWAIT
, argv
[0], argv
,
311 (const char * const *) environ
, directory
,
312 stdin_handle
, stdout_handle
, stderr_handle
);
331 if (stdin_handle
!= INVALID_HANDLE_VALUE
)
332 CloseHandle (stdin_handle
);
339 if (stdout_handle
!= INVALID_HANDLE_VALUE
)
340 CloseHandle (stdout_handle
);
343 # else /* __KLIBC__ */
344 if (!(directory
== NULL
&& strcmp (directory
, ".") == 0))
346 /* A directory argument is not supported in this implementation. */
347 saved_errno
= EINVAL
;
348 goto fail_with_saved_errno
;
355 /* Save standard file handles of parent process. */
356 if (pipe_stdin
|| prog_stdin
!= NULL
)
357 orig_stdin
= dup_safer_noinherit (STDIN_FILENO
);
358 if (pipe_stdout
|| prog_stdout
!= NULL
)
359 orig_stdout
= dup_safer_noinherit (STDOUT_FILENO
);
361 orig_stderr
= dup_safer_noinherit (STDERR_FILENO
);
363 /* Create standard file handles of child process. */
367 if ((!pipe_stdin
|| dup2 (ofd
[0], STDIN_FILENO
) >= 0)
368 && (!pipe_stdout
|| dup2 (ifd
[1], STDOUT_FILENO
) >= 0)
370 || ((nulloutfd
= open ("NUL", O_RDWR
, 0)) >= 0
371 && (nulloutfd
== STDERR_FILENO
372 || (dup2 (nulloutfd
, STDERR_FILENO
) >= 0
373 && close (nulloutfd
) >= 0))))
375 || prog_stdin
== NULL
376 || ((stdinfd
= open (prog_stdin
, O_RDONLY
, 0)) >= 0
377 && (stdinfd
== STDIN_FILENO
378 || (dup2 (stdinfd
, STDIN_FILENO
) >= 0
379 && close (stdinfd
) >= 0))))
381 || prog_stdout
== NULL
382 || ((stdoutfd
= open (prog_stdout
, O_WRONLY
, 0)) >= 0
383 && (stdoutfd
== STDOUT_FILENO
384 || (dup2 (stdoutfd
, STDOUT_FILENO
) >= 0
385 && close (stdoutfd
) >= 0)))))
386 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
387 but it inherits all open()ed or dup2()ed file handles (which is what
388 we want in the case of STD*_FILENO). */
390 child
= _spawnvpe (P_NOWAIT
, prog_path
, argv
+ 1,
391 (const char **) environ
);
392 # if 0 /* Executing arbitrary files as shell scripts is unsecure. */
393 if (child
== -1 && errno
== ENOEXEC
)
395 /* prog is not a native executable. Try to execute it as a
396 shell script. Note that prepare_spawn() has already prepended
397 a hidden element "sh.exe" to argv. */
398 child
= _spawnvpe (P_NOWAIT
, argv
[0], argv
,
399 (const char **) environ
);
412 /* Restore standard file handles of parent process. */
414 undup_safer_noinherit (orig_stderr
, STDERR_FILENO
);
415 if (pipe_stdout
|| prog_stdout
!= NULL
)
416 undup_safer_noinherit (orig_stdout
, STDOUT_FILENO
);
417 if (pipe_stdin
|| prog_stdin
!= NULL
)
418 undup_safer_noinherit (orig_stdin
, STDIN_FILENO
);
427 free (argv_mem_to_free
);
428 free (prog_path_to_free
);
436 goto fail_with_saved_errno
;
450 sigset_t blocked_signals
;
451 posix_spawn_file_actions_t actions
;
452 bool actions_allocated
;
453 posix_spawnattr_t attrs
;
454 bool attrs_allocated
;
459 if (pipe_safer (ifd
) < 0)
460 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
462 if (pipe_safer (ofd
) < 0)
463 error (EXIT_FAILURE
, errno
, _("cannot create pipe"));
464 /* Data flow diagram:
467 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
468 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
475 sigprocmask (SIG_SETMASK
, NULL
, &blocked_signals
);
476 block_fatal_signals ();
478 actions_allocated
= false;
479 attrs_allocated
= false;
480 if ((err
= posix_spawn_file_actions_init (&actions
)) != 0
481 || (actions_allocated
= true,
483 && (err
= posix_spawn_file_actions_adddup2 (&actions
,
484 ofd
[0], STDIN_FILENO
))
487 && (err
= posix_spawn_file_actions_adddup2 (&actions
,
488 ifd
[1], STDOUT_FILENO
))
491 && (err
= posix_spawn_file_actions_addclose (&actions
, ofd
[0]))
494 && (err
= posix_spawn_file_actions_addclose (&actions
, ifd
[1]))
497 && (err
= posix_spawn_file_actions_addclose (&actions
, ofd
[1]))
500 && (err
= posix_spawn_file_actions_addclose (&actions
, ifd
[0]))
503 && (err
= posix_spawn_file_actions_addopen (&actions
,
509 && prog_stdin
!= NULL
510 && (err
= posix_spawn_file_actions_addopen (&actions
,
512 prog_stdin
, O_RDONLY
,
516 && prog_stdout
!= NULL
517 && (err
= posix_spawn_file_actions_addopen (&actions
,
519 prog_stdout
, O_WRONLY
,
522 || (directory
!= NULL
523 && (err
= posix_spawn_file_actions_addchdir (&actions
,
526 && ((err
= posix_spawnattr_init (&attrs
)) != 0
527 || (attrs_allocated
= true,
528 # if defined _WIN32 && !defined __CYGWIN__
529 (err
= posix_spawnattr_setpgroup (&attrs
, 0)) != 0
530 || (err
= posix_spawnattr_setflags (&attrs
,
531 POSIX_SPAWN_SETPGROUP
))
534 (err
= posix_spawnattr_setsigmask (&attrs
,
537 || (err
= posix_spawnattr_setflags (&attrs
,
538 POSIX_SPAWN_SETSIGMASK
))
542 || (err
= (directory
!= NULL
543 ? posix_spawn (&child
, prog_path
, &actions
,
544 attrs_allocated
? &attrs
: NULL
,
545 (char * const *) prog_argv
, environ
)
546 : posix_spawnp (&child
, prog_path
, &actions
,
547 attrs_allocated
? &attrs
: NULL
,
548 (char * const *) prog_argv
, environ
)))
551 if (actions_allocated
)
552 posix_spawn_file_actions_destroy (&actions
);
554 posix_spawnattr_destroy (&attrs
);
556 unblock_fatal_signals ();
567 free (prog_path_to_free
);
569 goto fail_with_saved_errno
;
571 posix_spawn_file_actions_destroy (&actions
);
573 posix_spawnattr_destroy (&attrs
);
576 register_slave_subprocess (child
);
577 unblock_fatal_signals ();
583 free (prog_path_to_free
);
595 fail_with_saved_errno
:
596 if (exit_on_error
|| !null_stderr
)
597 error (exit_on_error
? EXIT_FAILURE
: 0, saved_errno
,
598 _("%s subprocess failed"), progname
);
603 /* Open a bidirectional pipe.
606 * parent -> fd[1] -> STDIN_FILENO -> child
607 * parent <- fd[0] <- STDOUT_FILENO <- child
612 create_pipe_bidi (const char *progname
,
613 const char *prog_path
, const char * const *prog_argv
,
614 const char *directory
,
616 bool slave_process
, bool exit_on_error
,
619 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
620 true, true, NULL
, NULL
,
621 null_stderr
, slave_process
, exit_on_error
,
626 /* Open a pipe for input from a child process.
627 * The child's stdin comes from a file.
630 * parent <- fd[0] <- STDOUT_FILENO <- child
634 create_pipe_in (const char *progname
,
635 const char *prog_path
, const char * const *prog_argv
,
636 const char *directory
,
637 const char *prog_stdin
, bool null_stderr
,
638 bool slave_process
, bool exit_on_error
,
642 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
643 false, true, prog_stdin
, NULL
,
644 null_stderr
, slave_process
, exit_on_error
,
651 /* Open a pipe for output to a child process.
652 * The child's stdout goes to a file.
655 * parent -> fd[0] -> STDIN_FILENO -> child
659 create_pipe_out (const char *progname
,
660 const char *prog_path
, const char * const *prog_argv
,
661 const char *directory
,
662 const char *prog_stdout
, bool null_stderr
,
663 bool slave_process
, bool exit_on_error
,
667 pid_t result
= create_pipe (progname
, prog_path
, prog_argv
, directory
,
668 true, false, NULL
, prog_stdout
,
669 null_stderr
, slave_process
, exit_on_error
,