findprog-in: Relicense under LGPLv2+.
[gnulib.git] / lib / spawn-pipe.c
blob209bbf57d06b19cd79c6cf4b12d5f45f19ac4d1b
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. */
20 #if defined __clang__
21 # pragma clang diagnostic ignored "-Wconditional-uninitialized"
22 #endif
24 #include <config.h>
26 /* Specification. */
27 #include "spawn-pipe.h"
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <signal.h>
33 #include <unistd.h>
35 #include "canonicalize.h"
36 #include "error.h"
37 #include "fatal-signal.h"
38 #include "filename.h"
39 #include "findprog.h"
40 #include "unistd-safer.h"
41 #include "wait-process.h"
42 #include "gettext.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"
51 # else
52 # include <io.h>
53 # endif
54 # include <process.h>
55 # include "windows-spawn.h"
57 #elif defined __KLIBC__
59 /* OS/2 kLIBC API. */
60 # include <process.h>
61 # include "os2-spawn.h"
63 #else
65 /* Unix API. */
66 # include <spawn.h>
68 #endif
71 #ifdef EINTR
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. */
77 static int
78 nonintr_close (int fd)
80 int retval;
83 retval = close (fd);
84 while (retval < 0 && errno == EINTR);
86 return retval;
88 #undef close /* avoid warning related to gnulib module unistd */
89 #define close nonintr_close
91 #if defined _WIN32 && ! defined __CYGWIN__
92 static int
93 nonintr_open (const char *pathname, int oflag, mode_t mode)
95 int retval;
98 retval = open (pathname, oflag, mode);
99 while (retval < 0 && errno == EINTR);
101 return retval;
103 # undef open /* avoid warning on VMS */
104 # define open nonintr_open
105 #endif
107 #endif
110 /* Open a pipe connected to a child process.
112 * write system read
113 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
114 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
115 * read system write
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.
123 static pid_t
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,
129 bool null_stderr,
130 bool slave_process, bool exit_on_error,
131 int fd[2])
133 int saved_errno;
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)
168 saved_errno = errno;
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))
177 abort ();
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. */
189 int ifd[2];
190 int ofd[2];
191 int child;
192 int nulloutfd;
193 int stdinfd;
194 int stdoutfd;
196 /* FIXME: Need to free memory allocated by prepare_spawn. */
197 prog_argv = prepare_spawn (prog_argv);
199 if (pipe_stdout)
200 if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
201 error (EXIT_FAILURE, errno, _("cannot create pipe"));
202 if (pipe_stdin)
203 if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
204 error (EXIT_FAILURE, errno, _("cannot create pipe"));
205 /* Data flow diagram:
207 * write system read
208 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
209 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
210 * read system write
214 child = -1;
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. */
221 nulloutfd = -1;
222 stdinfd = -1;
223 stdoutfd = -1;
224 if ((!null_stderr
225 || (nulloutfd = open ("NUL", O_RDWR, 0)) >= 0)
226 && (pipe_stdin
227 || prog_stdin == NULL
228 || (stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0)
229 && (pipe_stdout
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);
245 if (pipe_stdin)
247 HANDLE curr_process = GetCurrentProcess ();
248 HANDLE duplicate;
249 if (!DuplicateHandle (curr_process, stdin_handle,
250 curr_process, &duplicate,
251 0, TRUE, DUPLICATE_SAME_ACCESS))
253 errno = EBADF; /* arbitrary */
254 goto failed;
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);
263 if (pipe_stdout)
265 HANDLE curr_process = GetCurrentProcess ();
266 HANDLE duplicate;
267 if (!DuplicateHandle (curr_process, stdout_handle,
268 curr_process, &duplicate,
269 0, TRUE, DUPLICATE_SAME_ACCESS))
271 errno = EBADF; /* arbitrary */
272 goto failed;
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;
290 --prog_argv;
291 child = spawnpvech (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
292 (const char **) environ, directory,
293 stdin_handle, stdout_handle, stderr_handle);
296 failed:
297 if (child == -1)
298 saved_errno = errno;
299 if (stdinfd >= 0)
300 close (stdinfd);
301 if (stdoutfd >= 0)
302 close (stdoutfd);
303 if (nulloutfd >= 0)
304 close (nulloutfd);
306 if (must_close_ofd0)
307 close (ofd[0]);
308 if (must_close_ifd1)
309 close (ifd[1]);
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;
319 int orig_stdin;
320 int orig_stdout;
321 int orig_stderr;
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);
328 if (null_stderr)
329 orig_stderr = dup_safer_noinherit (STDERR_FILENO);
331 /* Create standard file handles of child process. */
332 nulloutfd = -1;
333 stdinfd = -1;
334 stdoutfd = -1;
335 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
336 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
337 && (!null_stderr
338 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
339 && (nulloutfd == STDERR_FILENO
340 || (dup2 (nulloutfd, STDERR_FILENO) >= 0
341 && close (nulloutfd) >= 0))))
342 && (pipe_stdin
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))))
348 && (pipe_stdout
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. */
365 --prog_argv;
366 child = _spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
367 (const char **) environ);
370 if (child == -1)
371 saved_errno = errno;
372 if (stdinfd >= 0)
373 close (stdinfd);
374 if (stdoutfd >= 0)
375 close (stdoutfd);
376 if (nulloutfd >= 0)
377 close (nulloutfd);
379 /* Restore standard file handles of parent process. */
380 if (null_stderr)
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);
387 if (pipe_stdin)
388 close (ofd[0]);
389 if (pipe_stdout)
390 close (ifd[1]);
391 # endif
393 free (prog_path_to_free);
395 if (child == -1)
397 if (pipe_stdout)
398 close (ifd[0]);
399 if (pipe_stdin)
400 close (ofd[1]);
401 goto fail_with_saved_errno;
404 if (pipe_stdout)
405 fd[0] = ifd[0];
406 if (pipe_stdin)
407 fd[1] = ofd[1];
408 return child;
410 #else
412 /* Unix API. */
413 int ifd[2];
414 int ofd[2];
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;
420 int err;
421 pid_t child;
423 if (pipe_stdout)
424 if (pipe_safer (ifd) < 0)
425 error (EXIT_FAILURE, errno, _("cannot create pipe"));
426 if (pipe_stdin)
427 if (pipe_safer (ofd) < 0)
428 error (EXIT_FAILURE, errno, _("cannot create pipe"));
429 /* Data flow diagram:
431 * write system read
432 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
433 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
434 * read system write
438 if (slave_process)
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,
447 (pipe_stdin
448 && (err = posix_spawn_file_actions_adddup2 (&actions,
449 ofd[0], STDIN_FILENO))
450 != 0)
451 || (pipe_stdout
452 && (err = posix_spawn_file_actions_adddup2 (&actions,
453 ifd[1], STDOUT_FILENO))
454 != 0)
455 || (pipe_stdin
456 && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
457 != 0)
458 || (pipe_stdout
459 && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
460 != 0)
461 || (pipe_stdin
462 && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
463 != 0)
464 || (pipe_stdout
465 && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
466 != 0)
467 || (null_stderr
468 && (err = posix_spawn_file_actions_addopen (&actions,
469 STDERR_FILENO,
470 "/dev/null", O_RDWR,
472 != 0)
473 || (!pipe_stdin
474 && prog_stdin != NULL
475 && (err = posix_spawn_file_actions_addopen (&actions,
476 STDIN_FILENO,
477 prog_stdin, O_RDONLY,
479 != 0)
480 || (!pipe_stdout
481 && prog_stdout != NULL
482 && (err = posix_spawn_file_actions_addopen (&actions,
483 STDOUT_FILENO,
484 prog_stdout, O_WRONLY,
486 != 0)
487 || (directory != NULL
488 && (err = posix_spawn_file_actions_addchdir (&actions,
489 directory)))
490 || (slave_process
491 && ((err = posix_spawnattr_init (&attrs)) != 0
492 || (attrs_allocated = true,
493 (err = posix_spawnattr_setsigmask (&attrs,
494 &blocked_signals))
495 != 0
496 || (err = posix_spawnattr_setflags (&attrs,
497 POSIX_SPAWN_SETSIGMASK))
498 != 0)))
499 || (err = (directory != NULL
500 ? posix_spawn (&child, prog_path, &actions,
501 attrs_allocated ? &attrs : NULL, prog_argv,
502 environ)
503 : posix_spawnp (&child, prog_path, &actions,
504 attrs_allocated ? &attrs : NULL, prog_argv,
505 environ)))
506 != 0))
508 if (actions_allocated)
509 posix_spawn_file_actions_destroy (&actions);
510 if (attrs_allocated)
511 posix_spawnattr_destroy (&attrs);
512 if (slave_process)
513 unblock_fatal_signals ();
514 if (pipe_stdout)
516 close (ifd[0]);
517 close (ifd[1]);
519 if (pipe_stdin)
521 close (ofd[0]);
522 close (ofd[1]);
524 free (prog_path_to_free);
525 saved_errno = err;
526 goto fail_with_saved_errno;
528 posix_spawn_file_actions_destroy (&actions);
529 if (attrs_allocated)
530 posix_spawnattr_destroy (&attrs);
531 if (slave_process)
533 register_slave_subprocess (child);
534 unblock_fatal_signals ();
536 if (pipe_stdin)
537 close (ofd[0]);
538 if (pipe_stdout)
539 close (ifd[1]);
540 free (prog_path_to_free);
542 if (pipe_stdout)
543 fd[0] = ifd[0];
544 if (pipe_stdin)
545 fd[1] = ofd[1];
546 return child;
548 #endif
550 fail_with_errno:
551 saved_errno = errno;
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);
556 errno = saved_errno;
557 return -1;
560 /* Open a bidirectional pipe.
562 * write system read
563 * parent -> fd[1] -> STDIN_FILENO -> child
564 * parent <- fd[0] <- STDOUT_FILENO <- child
565 * read system write
568 pid_t
569 create_pipe_bidi (const char *progname,
570 const char *prog_path, char **prog_argv,
571 const char *directory,
572 bool null_stderr,
573 bool slave_process, bool exit_on_error,
574 int fd[2])
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,
579 fd);
580 return result;
583 /* Open a pipe for input from a child process.
584 * The child's stdin comes from a file.
586 * read system write
587 * parent <- fd[0] <- STDOUT_FILENO <- child
590 pid_t
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,
596 int fd[1])
598 int iofd[2];
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,
602 iofd);
603 if (result != -1)
604 fd[0] = iofd[0];
605 return result;
608 /* Open a pipe for output to a child process.
609 * The child's stdout goes to a file.
611 * write system read
612 * parent -> fd[0] -> STDIN_FILENO -> child
615 pid_t
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,
621 int fd[1])
623 int iofd[2];
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,
627 iofd);
628 if (result != -1)
629 fd[0] = iofd[1];
630 return result;