fstat: Fix module dependency conditions.
[gnulib/ericb.git] / lib / spawn-pipe.c
blob7e8f241132885c6f628cc459c4b136ff4ef42cca
1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006-2017 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/>. */
19 #include <config.h>
21 /* Specification. */
22 #include "spawn-pipe.h"
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <signal.h>
28 #include <unistd.h>
30 #include "error.h"
31 #include "fatal-signal.h"
32 #include "unistd-safer.h"
33 #include "wait-process.h"
34 #include "gettext.h"
36 #define _(str) gettext (str)
38 #if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
39 || defined __KLIBC__)
41 /* Native Windows API. */
42 # include <process.h>
43 # include "w32spawn.h"
45 #else
47 /* Unix API. */
48 # include <spawn.h>
50 #endif
53 #ifdef EINTR
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. */
59 static int
60 nonintr_close (int fd)
62 int retval;
65 retval = close (fd);
66 while (retval < 0 && errno == EINTR);
68 return retval;
70 #define close nonintr_close
72 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
73 static int
74 nonintr_open (const char *pathname, int oflag, mode_t mode)
76 int retval;
79 retval = open (pathname, oflag, mode);
80 while (retval < 0 && errno == EINTR);
82 return retval;
84 # undef open /* avoid warning on VMS */
85 # define open nonintr_open
86 #endif
88 #endif
91 /* Open a pipe connected to a child process.
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
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.
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])
113 #if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
114 || defined __KLIBC__)
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;
132 /* FIXME: Need to free memory allocated by prepare_spawn. */
133 prog_argv = prepare_spawn (prog_argv);
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:
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
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;
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(). */
194 child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
195 (const char **) environ);
196 if (child < 0 && errno == ENOEXEC)
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);
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);
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);
223 if (pipe_stdin)
224 close (ofd[0]);
225 if (pipe_stdout)
226 close (ifd[1]);
227 if (child == -1)
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;
240 if (pipe_stdout)
241 fd[0] = ifd[0];
242 if (pipe_stdin)
243 fd[1] = ofd[1];
244 return child;
246 #else
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;
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:
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
274 if (slave_process)
276 sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
277 block_fatal_signals ();
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,
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,
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,
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))
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)
348 close (ifd[0]);
349 close (ifd[1]);
351 if (pipe_stdin)
353 close (ofd[0]);
354 close (ofd[1]);
356 errno = err;
357 return -1;
359 posix_spawn_file_actions_destroy (&actions);
360 if (attrs_allocated)
361 posix_spawnattr_destroy (&attrs);
362 if (slave_process)
364 register_slave_subprocess (child);
365 unblock_fatal_signals ();
367 if (pipe_stdin)
368 close (ofd[0]);
369 if (pipe_stdout)
370 close (ifd[1]);
372 if (pipe_stdout)
373 fd[0] = ifd[0];
374 if (pipe_stdin)
375 fd[1] = ofd[1];
376 return child;
378 #endif
381 /* Open a bidirectional pipe.
383 * write system read
384 * parent -> fd[1] -> STDIN_FILENO -> child
385 * parent <- fd[0] <- STDOUT_FILENO <- child
386 * read system write
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])
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;
403 /* Open a pipe for input from a child process.
404 * The child's stdin comes from a file.
406 * read system write
407 * parent <- fd[0] <- STDOUT_FILENO <- child
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])
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;
427 /* Open a pipe for output to a child process.
428 * The child's stdout goes to a file.
430 * write system read
431 * parent -> fd[0] -> STDIN_FILENO -> child
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])
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;