1/* Creation of subprocesses, communicating via pipes. 2 Copyright (C) 2001-2004, 2006-2012 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 "spawn-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 "unistd-safer.h" 33#include "wait-process.h" 34#include "gettext.h" 35 36#define _(str) gettext (str) 37 38#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 39 40/* Native Windows API. */ 41# include <process.h> 42# include "w32spawn.h" 43 44#else 45 46/* Unix API. */ 47# include <spawn.h> 48 49#endif 50 51/* The results of open() in this file are not used with fchdir, 52 therefore save some unnecessary work in fchdir.c. */ 53#undef open 54#undef close 55 56 57#ifdef EINTR 58 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. */ 62 63static int 64nonintr_close (int fd) 65{ 66 int retval; 67 68 do 69 retval = close (fd); 70 while (retval < 0 && errno == EINTR); 71 72 return retval; 73} 74#define close nonintr_close 75 76#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 77static int 78nonintr_open (const char *pathname, int oflag, mode_t mode) 79{ 80 int retval; 81 82 do 83 retval = open (pathname, oflag, mode); 84 while (retval < 0 && errno == EINTR); 85 86 return retval; 87} 88# undef open /* avoid warning on VMS */ 89# define open nonintr_open 90#endif 91 92#endif 93 94 95/* Open a pipe connected to a child process. 96 * 97 * write system read 98 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin 99 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout 100 * read system write 101 * 102 * At least one of pipe_stdin, pipe_stdout must be true. 103 * pipe_stdin and prog_stdin together determine the child's standard input. 104 * pipe_stdout and prog_stdout together determine the child's standard output. 105 * If pipe_stdin is true, prog_stdin is ignored. 106 * If pipe_stdout is true, prog_stdout is ignored. 107 */ 108static pid_t 109create_pipe (const char *progname, 110 const char *prog_path, char **prog_argv, 111 bool pipe_stdin, bool pipe_stdout, 112 const char *prog_stdin, const char *prog_stdout, 113 bool null_stderr, 114 bool slave_process, bool exit_on_error, 115 int fd[2]) 116{ 117#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 118 119 /* Native Windows API. 120 This uses _pipe(), dup2(), and spawnv(). It could also be implemented 121 using the low-level functions CreatePipe(), DuplicateHandle(), 122 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp 123 and cvs source code. */ 124 int ifd[2]; 125 int ofd[2]; 126 int orig_stdin; 127 int orig_stdout; 128 int orig_stderr; 129 int child; 130 int nulloutfd; 131 int stdinfd; 132 int stdoutfd; 133 int saved_errno; 134 135 /* FIXME: Need to free memory allocated by prepare_spawn. */ 136 prog_argv = prepare_spawn (prog_argv); 137 138 if (pipe_stdout) 139 if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0) 140 error (EXIT_FAILURE, errno, _("cannot create pipe")); 141 if (pipe_stdin) 142 if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0) 143 error (EXIT_FAILURE, errno, _("cannot create pipe")); 144/* Data flow diagram: 145 * 146 * write system read 147 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin 148 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout 149 * read system write 150 * 151 */ 152 153 /* Save standard file handles of parent process. */ 154 if (pipe_stdin || prog_stdin != NULL) 155 orig_stdin = dup_safer_noinherit (STDIN_FILENO); 156 if (pipe_stdout || prog_stdout != NULL) 157 orig_stdout = dup_safer_noinherit (STDOUT_FILENO); 158 if (null_stderr) 159 orig_stderr = dup_safer_noinherit (STDERR_FILENO); 160 child = -1; 161 162 /* Create standard file handles of child process. */ 163 nulloutfd = -1; 164 stdinfd = -1; 165 stdoutfd = -1; 166 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0) 167 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0) 168 && (!null_stderr 169 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0 170 && (nulloutfd == STDERR_FILENO 171 || (dup2 (nulloutfd, STDERR_FILENO) >= 0 172 && close (nulloutfd) >= 0)))) 173 && (pipe_stdin 174 || prog_stdin == NULL 175 || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0 176 && (stdinfd == STDIN_FILENO 177 || (dup2 (stdinfd, STDIN_FILENO) >= 0 178 && close (stdinfd) >= 0)))) 179 && (pipe_stdout 180 || prog_stdout == NULL 181 || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0 182 && (stdoutfd == STDOUT_FILENO 183 || (dup2 (stdoutfd, STDOUT_FILENO) >= 0 184 && close (stdoutfd) >= 0))))) 185 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1], 186 but it inherits all open()ed or dup2()ed file handles (which is what 187 we want in the case of STD*_FILENO). */ 188 /* Use spawnvpe and pass the environment explicitly. This is needed if 189 the program has modified the environment using putenv() or [un]setenv(). 190 On Windows, programs have two environments, one in the "environment 191 block" of the process and managed through SetEnvironmentVariable(), and 192 one inside the process, in the location retrieved by the 'environ' 193 macro. When using spawnvp() without 'e', the child process inherits a 194 copy of the environment block - ignoring the effects of putenv() and 195 [un]setenv(). */ 196 { 197 child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv, 198 (const char **) environ); 199 if (child < 0 && errno == ENOEXEC) 200 { 201 /* prog is not a native executable. Try to execute it as a 202 shell script. Note that prepare_spawn() has already prepended 203 a hidden element "sh.exe" to prog_argv. */ 204 --prog_argv; 205 child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv, 206 (const char **) environ); 207 } 208 } 209 if (child == -1) 210 saved_errno = errno; 211 if (stdinfd >= 0) 212 close (stdinfd); 213 if (stdoutfd >= 0) 214 close (stdoutfd); 215 if (nulloutfd >= 0) 216 close (nulloutfd); 217 218 /* Restore standard file handles of parent process. */ 219 if (null_stderr) 220 undup_safer_noinherit (orig_stderr, STDERR_FILENO); 221 if (pipe_stdout || prog_stdout != NULL) 222 undup_safer_noinherit (orig_stdout, STDOUT_FILENO); 223 if (pipe_stdin || prog_stdin != NULL) 224 undup_safer_noinherit (orig_stdin, STDIN_FILENO); 225 226 if (pipe_stdin) 227 close (ofd[0]); 228 if (pipe_stdout) 229 close (ifd[1]); 230 if (child == -1) 231 { 232 if (exit_on_error || !null_stderr) 233 error (exit_on_error ? EXIT_FAILURE : 0, saved_errno, 234 _("%s subprocess failed"), progname); 235 if (pipe_stdout) 236 close (ifd[0]); 237 if (pipe_stdin) 238 close (ofd[1]); 239 errno = saved_errno; 240 return -1; 241 } 242 243 if (pipe_stdout) 244 fd[0] = ifd[0]; 245 if (pipe_stdin) 246 fd[1] = ofd[1]; 247 return child; 248 249#else 250 251 /* Unix API. */ 252 int ifd[2]; 253 int ofd[2]; 254 sigset_t blocked_signals; 255 posix_spawn_file_actions_t actions; 256 bool actions_allocated; 257 posix_spawnattr_t attrs; 258 bool attrs_allocated; 259 int err; 260 pid_t child; 261 262 if (pipe_stdout) 263 if (pipe_safer (ifd) < 0) 264 error (EXIT_FAILURE, errno, _("cannot create pipe")); 265 if (pipe_stdin) 266 if (pipe_safer (ofd) < 0) 267 error (EXIT_FAILURE, errno, _("cannot create pipe")); 268/* Data flow diagram: 269 * 270 * write system read 271 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin 272 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout 273 * read system write 274 * 275 */ 276 277 if (slave_process) 278 { 279 sigprocmask (SIG_SETMASK, NULL, &blocked_signals); 280 block_fatal_signals (); 281 } 282 actions_allocated = false; 283 attrs_allocated = false; 284 if ((err = posix_spawn_file_actions_init (&actions)) != 0 285 || (actions_allocated = true, 286 (pipe_stdin 287 && (err = posix_spawn_file_actions_adddup2 (&actions, 288 ofd[0], STDIN_FILENO)) 289 != 0) 290 || (pipe_stdout 291 && (err = posix_spawn_file_actions_adddup2 (&actions, 292 ifd[1], STDOUT_FILENO)) 293 != 0) 294 || (pipe_stdin 295 && (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) 296 != 0) 297 || (pipe_stdout 298 && (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) 299 != 0) 300 || (pipe_stdin 301 && (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) 302 != 0) 303 || (pipe_stdout 304 && (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) 305 != 0) 306 || (null_stderr 307 && (err = posix_spawn_file_actions_addopen (&actions, 308 STDERR_FILENO, 309 "/dev/null", O_RDWR, 310 0)) 311 != 0) 312 || (!pipe_stdin 313 && prog_stdin != NULL 314 && (err = posix_spawn_file_actions_addopen (&actions, 315 STDIN_FILENO, 316 prog_stdin, O_RDONLY, 317 0)) 318 != 0) 319 || (!pipe_stdout 320 && prog_stdout != NULL 321 && (err = posix_spawn_file_actions_addopen (&actions, 322 STDOUT_FILENO, 323 prog_stdout, O_WRONLY, 324 0)) 325 != 0) 326 || (slave_process 327 && ((err = posix_spawnattr_init (&attrs)) != 0 328 || (attrs_allocated = true, 329 (err = posix_spawnattr_setsigmask (&attrs, 330 &blocked_signals)) 331 != 0 332 || (err = posix_spawnattr_setflags (&attrs, 333 POSIX_SPAWN_SETSIGMASK)) 334 != 0))) 335 || (err = posix_spawnp (&child, prog_path, &actions, 336 attrs_allocated ? &attrs : NULL, prog_argv, 337 environ)) 338 != 0)) 339 { 340 if (actions_allocated) 341 posix_spawn_file_actions_destroy (&actions); 342 if (attrs_allocated) 343 posix_spawnattr_destroy (&attrs); 344 if (slave_process) 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); 349 if (pipe_stdout) 350 { 351 close (ifd[0]); 352 close (ifd[1]); 353 } 354 if (pipe_stdin) 355 { 356 close (ofd[0]); 357 close (ofd[1]); 358 } 359 errno = err; 360 return -1; 361 } 362 posix_spawn_file_actions_destroy (&actions); 363 if (attrs_allocated) 364 posix_spawnattr_destroy (&attrs); 365 if (slave_process) 366 { 367 register_slave_subprocess (child); 368 unblock_fatal_signals (); 369 } 370 if (pipe_stdin) 371 close (ofd[0]); 372 if (pipe_stdout) 373 close (ifd[1]); 374 375 if (pipe_stdout) 376 fd[0] = ifd[0]; 377 if (pipe_stdin) 378 fd[1] = ofd[1]; 379 return child; 380 381#endif 382} 383 384/* Open a bidirectional pipe. 385 * 386 * write system read 387 * parent -> fd[1] -> STDIN_FILENO -> child 388 * parent <- fd[0] <- STDOUT_FILENO <- child 389 * read system write 390 * 391 */ 392pid_t 393create_pipe_bidi (const char *progname, 394 const char *prog_path, char **prog_argv, 395 bool null_stderr, 396 bool slave_process, bool exit_on_error, 397 int fd[2]) 398{ 399 pid_t result = create_pipe (progname, prog_path, prog_argv, 400 true, true, NULL, NULL, 401 null_stderr, slave_process, exit_on_error, 402 fd); 403 return result; 404} 405 406/* Open a pipe for input from a child process. 407 * The child's stdin comes from a file. 408 * 409 * read system write 410 * parent <- fd[0] <- STDOUT_FILENO <- child 411 * 412 */ 413pid_t 414create_pipe_in (const char *progname, 415 const char *prog_path, char **prog_argv, 416 const char *prog_stdin, bool null_stderr, 417 bool slave_process, bool exit_on_error, 418 int fd[1]) 419{ 420 int iofd[2]; 421 pid_t result = create_pipe (progname, prog_path, prog_argv, 422 false, true, prog_stdin, NULL, 423 null_stderr, slave_process, exit_on_error, 424 iofd); 425 if (result != -1) 426 fd[0] = iofd[0]; 427 return result; 428} 429 430/* Open a pipe for output to a child process. 431 * The child's stdout goes to a file. 432 * 433 * write system read 434 * parent -> fd[0] -> STDIN_FILENO -> child 435 * 436 */ 437pid_t 438create_pipe_out (const char *progname, 439 const char *prog_path, char **prog_argv, 440 const char *prog_stdout, bool null_stderr, 441 bool slave_process, bool exit_on_error, 442 int fd[1]) 443{ 444 int iofd[2]; 445 pid_t result = create_pipe (progname, prog_path, prog_argv, 446 true, false, NULL, prog_stdout, 447 null_stderr, slave_process, exit_on_error, 448 iofd); 449 if (result != -1) 450 fd[0] = iofd[1]; 451 return result; 452} 453