1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
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 2, or (at your option)
8 any later version.
9
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.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19
20 #include <config.h>
21
22 /* Specification. */
23 #include "pipe.h"
24
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <signal.h>
29 #include <unistd.h>
30
31 #include "error.h"
32 #include "exit.h"
33 #include "fatal-signal.h"
34 #include "wait-process.h"
35 #include "gettext.h"
36
37 #define _(str) gettext (str)
38
39 #if defined _MSC_VER || defined __MINGW32__
40
41 /* Native Woe32 API. */
42 # include <process.h>
43 # include "w32spawn.h"
44
45 #else
46
47 /* Unix API. */
48 # ifdef HAVE_POSIX_SPAWN
49 # include <spawn.h>
50 # else
51 # ifdef HAVE_VFORK_H
52 # include <vfork.h>
53 # endif
54 # endif
55
56 #endif
57
58 #ifndef HAVE_ENVIRON_DECL
59 extern char **environ;
60 #endif
61
62 #ifndef STDIN_FILENO
63 # define STDIN_FILENO 0
64 #endif
65 #ifndef STDOUT_FILENO
66 # define STDOUT_FILENO 1
67 #endif
68 #ifndef STDERR_FILENO
69 # define STDERR_FILENO 2
70 #endif
71
72
73 #ifdef EINTR
74
75 /* EINTR handling for close().
76 These functions can return -1/EINTR even though we don't have any
77 signal handlers set up, namely when we get interrupted via SIGSTOP. */
78
79 static inline int
nonintr_close(int fd)80 nonintr_close (int fd)
81 {
82 int retval;
83
84 do
85 retval = close (fd);
86 while (retval < 0 && errno == EINTR);
87
88 return retval;
89 }
90 #define close nonintr_close
91
92 static inline int
nonintr_open(const char * pathname,int oflag,mode_t mode)93 nonintr_open (const char *pathname, int oflag, mode_t mode)
94 {
95 int retval;
96
97 do
98 retval = open (pathname, oflag, mode);
99 while (retval < 0 && errno == EINTR);
100
101 return retval;
102 }
103 #undef open /* avoid warning on VMS */
104 #define open nonintr_open
105
106 #endif
107
108
109 /* Open a pipe connected to a child process.
110 *
111 * write system read
112 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
113 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
114 * read system write
115 *
116 * At least one of pipe_stdin, pipe_stdout must be true.
117 * pipe_stdin and prog_stdin together determine the child's standard input.
118 * pipe_stdout and prog_stdout together determine the child's standard output.
119 * If pipe_stdin is true, prog_stdin is ignored.
120 * If pipe_stdout is true, prog_stdout is ignored.
121 */
122 static pid_t
create_pipe(const char * progname,const char * prog_path,char ** prog_argv,bool pipe_stdin,bool pipe_stdout,const char * prog_stdin,const char * prog_stdout,bool null_stderr,bool slave_process,bool exit_on_error,int fd[2])123 create_pipe (const char *progname,
124 const char *prog_path, char **prog_argv,
125 bool pipe_stdin, bool pipe_stdout,
126 const char *prog_stdin, const char *prog_stdout,
127 bool null_stderr,
128 bool slave_process, bool exit_on_error,
129 int fd[2])
130 {
131 #if defined _MSC_VER || defined __MINGW32__
132
133 /* Native Woe32 API.
134 This uses _pipe(), dup2(), and spawnv(). It could also be implemented
135 using the low-level functions CreatePipe(), DuplicateHandle(),
136 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
137 and cvs source code. */
138 int ifd[2];
139 int ofd[2];
140 int orig_stdin;
141 int orig_stdout;
142 int orig_stderr;
143 int child;
144 int nulloutfd;
145 int stdinfd;
146 int stdoutfd;
147
148 prog_argv = prepare_spawn (prog_argv);
149
150 if (pipe_stdout)
151 if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0)
152 error (EXIT_FAILURE, errno, _("cannot create pipe"));
153 if (pipe_stdin)
154 if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0)
155 error (EXIT_FAILURE, errno, _("cannot create pipe"));
156 /* Data flow diagram:
157 *
158 * write system read
159 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
160 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
161 * read system write
162 *
163 */
164
165 /* Save standard file handles of parent process. */
166 if (pipe_stdin || prog_stdin != NULL)
167 orig_stdin = dup_noinherit (STDIN_FILENO);
168 if (pipe_stdout || prog_stdout != NULL)
169 orig_stdout = dup_noinherit (STDOUT_FILENO);
170 if (null_stderr)
171 orig_stderr = dup_noinherit (STDERR_FILENO);
172 child = -1;
173
174 /* Create standard file handles of child process. */
175 nulloutfd = -1;
176 stdinfd = -1;
177 stdoutfd = -1;
178 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
179 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
180 && (!null_stderr
181 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
182 && (nulloutfd == STDERR_FILENO
183 || (dup2 (nulloutfd, STDERR_FILENO) >= 0
184 && close (nulloutfd) >= 0))))
185 && (pipe_stdin
186 || prog_stdin == NULL
187 || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
188 && (stdinfd == STDIN_FILENO
189 || (dup2 (stdinfd, STDIN_FILENO) >= 0
190 && close (stdinfd) >= 0))))
191 && (pipe_stdout
192 || prog_stdout == NULL
193 || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
194 && (stdoutfd == STDOUT_FILENO
195 || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
196 && close (stdoutfd) >= 0)))))
197 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
198 but it inherits all open()ed or dup2()ed file handles (which is what
199 we want in the case of STD*_FILENO) and also orig_stdin,
200 orig_stdout, orig_stderr (which is not explicitly wanted but
201 harmless). */
202 child = spawnvp (P_NOWAIT, prog_path, prog_argv);
203 if (stdinfd >= 0)
204 close (stdinfd);
205 if (stdoutfd >= 0)
206 close (stdoutfd);
207 if (nulloutfd >= 0)
208 close (nulloutfd);
209
210 /* Restore standard file handles of parent process. */
211 if (null_stderr)
212 dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
213 if (pipe_stdout || prog_stdout != NULL)
214 dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
215 if (pipe_stdin || prog_stdin != NULL)
216 dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
217
218 if (pipe_stdin)
219 close (ofd[0]);
220 if (pipe_stdout)
221 close (ifd[1]);
222 if (child == -1)
223 {
224 if (exit_on_error || !null_stderr)
225 error (exit_on_error ? EXIT_FAILURE : 0, errno,
226 _("%s subprocess failed"), progname);
227 if (pipe_stdout)
228 close (ifd[0]);
229 if (pipe_stdin)
230 close (ofd[1]);
231 return -1;
232 }
233
234 if (pipe_stdout)
235 fd[0] = ifd[0];
236 if (pipe_stdin)
237 fd[1] = ofd[1];
238 return child;
239
240 #else
241
242 /* Unix API. */
243 int ifd[2];
244 int ofd[2];
245 # if HAVE_POSIX_SPAWN
246 sigset_t blocked_signals;
247 posix_spawn_file_actions_t actions;
248 bool actions_allocated;
249 posix_spawnattr_t attrs;
250 bool attrs_allocated;
251 int err;
252 pid_t child;
253 # else
254 int child;
255 # endif
256
257 if (pipe_stdout)
258 if (pipe (ifd) < 0)
259 error (EXIT_FAILURE, errno, _("cannot create pipe"));
260 if (pipe_stdin)
261 if (pipe (ofd) < 0)
262 error (EXIT_FAILURE, errno, _("cannot create pipe"));
263 /* Data flow diagram:
264 *
265 * write system read
266 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
267 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
268 * read system write
269 *
270 */
271
272 # if HAVE_POSIX_SPAWN
273 if (slave_process)
274 {
275 sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
276 block_fatal_signals ();
277 }
278 actions_allocated = false;
279 attrs_allocated = false;
280 if ((err = posix_spawn_file_actions_init (&actions)) != 0
281 || (actions_allocated = true,
282 (pipe_stdin
283 && (err = posix_spawn_file_actions_adddup2 (&actions,
284 ofd[0], STDIN_FILENO))
285 != 0)
286 || (pipe_stdout
287 && (err = posix_spawn_file_actions_adddup2 (&actions,
288 ifd[1], STDOUT_FILENO))
289 != 0)
290 || (pipe_stdin
291 && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
292 != 0)
293 || (pipe_stdout
294 && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
295 != 0)
296 || (pipe_stdin
297 && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
298 != 0)
299 || (pipe_stdout
300 && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
301 != 0)
302 || (null_stderr
303 && (err = posix_spawn_file_actions_addopen (&actions,
304 STDERR_FILENO,
305 "/dev/null", O_RDWR,
306 0))
307 != 0)
308 || (!pipe_stdin
309 && prog_stdin != NULL
310 && (err = posix_spawn_file_actions_addopen (&actions,
311 STDIN_FILENO,
312 prog_stdin, O_RDONLY,
313 0))
314 != 0)
315 || (!pipe_stdout
316 && prog_stdout != NULL
317 && (err = posix_spawn_file_actions_addopen (&actions,
318 STDOUT_FILENO,
319 prog_stdout, O_WRONLY,
320 0))
321 != 0)
322 || (slave_process
323 && ((err = posix_spawnattr_init (&attrs)) != 0
324 || (attrs_allocated = true,
325 (err = posix_spawnattr_setsigmask (&attrs,
326 &blocked_signals))
327 != 0
328 || (err = posix_spawnattr_setflags (&attrs,
329 POSIX_SPAWN_SETSIGMASK))
330 != 0)))
331 || (err = posix_spawnp (&child, prog_path, &actions,
332 attrs_allocated ? &attrs : NULL, prog_argv,
333 environ))
334 != 0))
335 {
336 if (actions_allocated)
337 posix_spawn_file_actions_destroy (&actions);
338 if (attrs_allocated)
339 posix_spawnattr_destroy (&attrs);
340 if (slave_process)
341 unblock_fatal_signals ();
342 if (exit_on_error || !null_stderr)
343 error (exit_on_error ? EXIT_FAILURE : 0, err,
344 _("%s subprocess failed"), progname);
345 if (pipe_stdout)
346 {
347 close (ifd[0]);
348 close (ifd[1]);
349 }
350 if (pipe_stdin)
351 {
352 close (ofd[0]);
353 close (ofd[1]);
354 }
355 return -1;
356 }
357 posix_spawn_file_actions_destroy (&actions);
358 if (attrs_allocated)
359 posix_spawnattr_destroy (&attrs);
360 # else
361 if (slave_process)
362 block_fatal_signals ();
363 /* Use vfork() instead of fork() for efficiency. */
364 if ((child = vfork ()) == 0)
365 {
366 /* Child process code. */
367 int nulloutfd;
368 int stdinfd;
369 int stdoutfd;
370
371 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
372 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
373 && (!pipe_stdin || close (ofd[0]) >= 0)
374 && (!pipe_stdout || close (ifd[1]) >= 0)
375 && (!pipe_stdin || close (ofd[1]) >= 0)
376 && (!pipe_stdout || close (ifd[0]) >= 0)
377 && (!null_stderr
378 || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
379 && (nulloutfd == STDERR_FILENO
380 || (dup2 (nulloutfd, STDERR_FILENO) >= 0
381 && close (nulloutfd) >= 0))))
382 && (pipe_stdin
383 || prog_stdin == NULL
384 || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
385 && (stdinfd == STDIN_FILENO
386 || (dup2 (stdinfd, STDIN_FILENO) >= 0
387 && close (stdinfd) >= 0))))
388 && (pipe_stdout
389 || prog_stdout == NULL
390 || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
391 && (stdoutfd == STDOUT_FILENO
392 || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
393 && close (stdoutfd) >= 0))))
394 && (!slave_process || (unblock_fatal_signals (), true)))
395 execvp (prog_path, prog_argv);
396 _exit (127);
397 }
398 if (child == -1)
399 {
400 if (slave_process)
401 unblock_fatal_signals ();
402 if (exit_on_error || !null_stderr)
403 error (exit_on_error ? EXIT_FAILURE : 0, errno,
404 _("%s subprocess failed"), progname);
405 if (pipe_stdout)
406 {
407 close (ifd[0]);
408 close (ifd[1]);
409 }
410 if (pipe_stdin)
411 {
412 close (ofd[0]);
413 close (ofd[1]);
414 }
415 return -1;
416 }
417 # endif
418 if (slave_process)
419 {
420 register_slave_subprocess (child);
421 unblock_fatal_signals ();
422 }
423 if (pipe_stdin)
424 close (ofd[0]);
425 if (pipe_stdout)
426 close (ifd[1]);
427
428 if (pipe_stdout)
429 fd[0] = ifd[0];
430 if (pipe_stdin)
431 fd[1] = ofd[1];
432 return child;
433
434 #endif
435 }
436
437 /* Open a bidirectional pipe.
438 *
439 * write system read
440 * parent -> fd[1] -> STDIN_FILENO -> child
441 * parent <- fd[0] <- STDOUT_FILENO <- child
442 * read system write
443 *
444 */
445 pid_t
create_pipe_bidi(const char * progname,const char * prog_path,char ** prog_argv,bool null_stderr,bool slave_process,bool exit_on_error,int fd[2])446 create_pipe_bidi (const char *progname,
447 const char *prog_path, char **prog_argv,
448 bool null_stderr,
449 bool slave_process, bool exit_on_error,
450 int fd[2])
451 {
452 pid_t result = create_pipe (progname, prog_path, prog_argv,
453 true, true, NULL, NULL,
454 null_stderr, slave_process, exit_on_error,
455 fd);
456 return result;
457 }
458
459 /* Open a pipe for input from a child process.
460 * The child's stdin comes from a file.
461 *
462 * read system write
463 * parent <- fd[0] <- STDOUT_FILENO <- child
464 *
465 */
466 pid_t
create_pipe_in(const char * progname,const char * prog_path,char ** prog_argv,const char * prog_stdin,bool null_stderr,bool slave_process,bool exit_on_error,int fd[1])467 create_pipe_in (const char *progname,
468 const char *prog_path, char **prog_argv,
469 const char *prog_stdin, bool null_stderr,
470 bool slave_process, bool exit_on_error,
471 int fd[1])
472 {
473 int iofd[2];
474 pid_t result = create_pipe (progname, prog_path, prog_argv,
475 false, true, prog_stdin, NULL,
476 null_stderr, slave_process, exit_on_error,
477 iofd);
478 if (result != -1)
479 fd[0] = iofd[0];
480 return result;
481 }
482
483 /* Open a pipe for output to a child process.
484 * The child's stdout goes to a file.
485 *
486 * write system read
487 * parent -> fd[0] -> STDIN_FILENO -> child
488 *
489 */
490 pid_t
create_pipe_out(const char * progname,const char * prog_path,char ** prog_argv,const char * prog_stdout,bool null_stderr,bool slave_process,bool exit_on_error,int fd[1])491 create_pipe_out (const char *progname,
492 const char *prog_path, char **prog_argv,
493 const char *prog_stdout, bool null_stderr,
494 bool slave_process, bool exit_on_error,
495 int fd[1])
496 {
497 int iofd[2];
498 pid_t result = create_pipe (progname, prog_path, prog_argv,
499 true, false, NULL, prog_stdout,
500 null_stderr, slave_process, exit_on_error,
501 iofd);
502 if (result != -1)
503 fd[0] = iofd[1];
504 return result;
505 }
506