1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006-2009 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 <http://www.gnu.org/licenses/>. */
31 #include "fatal-signal.h"
32 #include "unistd-safer.h"
33 #include "wait-process.h"
36 #define _(str) gettext (str)
38 #if defined _MSC_VER || defined __MINGW32__
40 /* Native Woe32 API. */
42 # include "w32spawn.h"
51 /* The results of open() in this file are not used with fchdir,
52 therefore save some unnecessary work in fchdir.c. */
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. */
64 nonintr_close (int fd)
70 while (retval < 0 && errno == EINTR);
74 #define close nonintr_close
77 nonintr_open (const char *pathname, int oflag, mode_t mode)
82 retval = open (pathname, oflag, mode);
83 while (retval < 0 && errno == EINTR);
87 #undef open /* avoid warning on VMS */
88 #define open nonintr_open
93 /* Open a pipe connected to a child process.
96 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
97 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
100 * At least one of pipe_stdin, pipe_stdout must be true.
101 * pipe_stdin and prog_stdin together determine the child's standard input.
102 * pipe_stdout and prog_stdout together determine the child's standard output.
103 * If pipe_stdin is true, prog_stdin is ignored.
104 * If pipe_stdout is true, prog_stdout is ignored.
107 create_pipe (const char *progname,
108 const char *prog_path, char **prog_argv,
109 bool pipe_stdin, bool pipe_stdout,
110 const char *prog_stdin, const char *prog_stdout,
112 bool slave_process, bool exit_on_error,
115 #if defined _MSC_VER || defined __MINGW32__
118 This uses _pipe(), dup2(), and spawnv(). It could also be implemented
119 using the low-level functions CreatePipe(), DuplicateHandle(),
120 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
121 and cvs source code. */
132 /* FIXME: Need to free memory allocated by prepare_spawn. */
133 prog_argv = prepare_spawn (prog_argv);
136 if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0
137 || (ifd[0] = fd_safer (ifd[0])) < 0)
138 error (EXIT_FAILURE, errno, _("cannot create pipe"));
140 if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0
141 || (ofd[1] = fd_safer (ofd[1])) < 0)
142 error (EXIT_FAILURE, errno, _("cannot create pipe"));
143 /* Data flow diagram:
146 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
147 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
152 /* Save standard file handles of parent process. */
153 if (pipe_stdin || prog_stdin != NULL)
154 orig_stdin = dup_noinherit (STDIN_FILENO);
155 if (pipe_stdout || prog_stdout != NULL)
156 orig_stdout = dup_noinherit (STDOUT_FILENO);
158 orig_stderr = dup_noinherit (STDERR_FILENO);
161 /* Create standard file handles of child process. */
165 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
166 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
168 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
169 && (nulloutfd == STDERR_FILENO
170 || (dup2 (nulloutfd, STDERR_FILENO) >= 0
171 && close (nulloutfd) >= 0))))
173 || prog_stdin == NULL
174 || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
175 && (stdinfd == STDIN_FILENO
176 || (dup2 (stdinfd, STDIN_FILENO) >= 0
177 && close (stdinfd) >= 0))))
179 || prog_stdout == NULL
180 || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
181 && (stdoutfd == STDOUT_FILENO
182 || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
183 && close (stdoutfd) >= 0)))))
184 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
185 but it inherits all open()ed or dup2()ed file handles (which is what
186 we want in the case of STD*_FILENO) and also orig_stdin,
187 orig_stdout, orig_stderr (which is not explicitly wanted but
189 /* Use spawnvpe and pass the environment explicitly. This is needed if
190 the program has modified the environment using putenv() or [un]setenv().
191 On Windows, programs have two environments, one in the "environment
192 block" of the process and managed through SetEnvironmentVariable(), and
193 one inside the process, in the location retrieved by the 'environ'
194 macro. When using spawnvp() without 'e', the child process inherits a
195 copy of the environment block - ignoring the effects of putenv() and
198 child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
199 (const char **) environ);
200 if (child < 0 && errno == ENOEXEC)
202 /* prog is not an native executable. Try to execute it as a
203 shell script. Note that prepare_spawn() has already prepended
204 a hidden element "sh.exe" to prog_argv. */
206 child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
207 (const char **) environ);
217 /* Restore standard file handles of parent process. */
219 dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
220 if (pipe_stdout || prog_stdout != NULL)
221 dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
222 if (pipe_stdin || prog_stdin != NULL)
223 dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
231 if (exit_on_error || !null_stderr)
232 error (exit_on_error ? EXIT_FAILURE : 0, errno,
233 _("%s subprocess failed"), progname);
252 sigset_t blocked_signals;
253 posix_spawn_file_actions_t actions;
254 bool actions_allocated;
255 posix_spawnattr_t attrs;
256 bool attrs_allocated;
262 || (ifd[0] = fd_safer (ifd[0])) < 0)
263 error (EXIT_FAILURE, errno, _("cannot create pipe"));
266 || (ofd[1] = fd_safer (ofd[1])) < 0)
267 error (EXIT_FAILURE, errno, _("cannot create pipe"));
268 /* Data flow diagram:
271 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
272 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
279 sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
280 block_fatal_signals ();
282 actions_allocated = false;
283 attrs_allocated = false;
284 if ((err = posix_spawn_file_actions_init (&actions)) != 0
285 || (actions_allocated = true,
287 && (err = posix_spawn_file_actions_adddup2 (&actions,
288 ofd[0], STDIN_FILENO))
291 && (err = posix_spawn_file_actions_adddup2 (&actions,
292 ifd[1], STDOUT_FILENO))
295 && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
298 && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
301 && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
304 && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
307 && (err = posix_spawn_file_actions_addopen (&actions,
313 && prog_stdin != NULL
314 && (err = posix_spawn_file_actions_addopen (&actions,
316 prog_stdin, O_RDONLY,
320 && prog_stdout != NULL
321 && (err = posix_spawn_file_actions_addopen (&actions,
323 prog_stdout, O_WRONLY,
327 && ((err = posix_spawnattr_init (&attrs)) != 0
328 || (attrs_allocated = true,
329 (err = posix_spawnattr_setsigmask (&attrs,
332 || (err = posix_spawnattr_setflags (&attrs,
333 POSIX_SPAWN_SETSIGMASK))
335 || (err = posix_spawnp (&child, prog_path, &actions,
336 attrs_allocated ? &attrs : NULL, prog_argv,
340 if (actions_allocated)
341 posix_spawn_file_actions_destroy (&actions);
343 posix_spawnattr_destroy (&attrs);
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);
361 posix_spawn_file_actions_destroy (&actions);
363 posix_spawnattr_destroy (&attrs);
366 register_slave_subprocess (child);
367 unblock_fatal_signals ();
383 /* Open a bidirectional pipe.
386 * parent -> fd[1] -> STDIN_FILENO -> child
387 * parent <- fd[0] <- STDOUT_FILENO <- child
392 create_pipe_bidi (const char *progname,
393 const char *prog_path, char **prog_argv,
395 bool slave_process, bool exit_on_error,
398 pid_t result = create_pipe (progname, prog_path, prog_argv,
399 true, true, NULL, NULL,
400 null_stderr, slave_process, exit_on_error,
405 /* Open a pipe for input from a child process.
406 * The child's stdin comes from a file.
409 * parent <- fd[0] <- STDOUT_FILENO <- child
413 create_pipe_in (const char *progname,
414 const char *prog_path, char **prog_argv,
415 const char *prog_stdin, bool null_stderr,
416 bool slave_process, bool exit_on_error,
420 pid_t result = create_pipe (progname, prog_path, prog_argv,
421 false, true, prog_stdin, NULL,
422 null_stderr, slave_process, exit_on_error,
429 /* Open a pipe for output to a child process.
430 * The child's stdout goes to a file.
433 * parent -> fd[0] -> STDIN_FILENO -> child
437 create_pipe_out (const char *progname,
438 const char *prog_path, char **prog_argv,
439 const char *prog_stdout, bool null_stderr,
440 bool slave_process, bool exit_on_error,
444 pid_t result = create_pipe (progname, prog_path, prog_argv,
445 true, false, NULL, prog_stdout,
446 null_stderr, slave_process, exit_on_error,