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