This source file includes following definitions.
- nonintr_close
- nonintr_open
- create_pipe
- create_pipe_bidi
- create_pipe_in
- create_pipe_out
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 #if defined __clang__
  21 # pragma clang diagnostic ignored "-Wconditional-uninitialized"
  22 #endif
  23 
  24 #include <config.h>
  25 
  26 
  27 #include "spawn-pipe.h"
  28 
  29 #include <errno.h>
  30 #include <fcntl.h>
  31 #include <stdlib.h>
  32 #include <signal.h>
  33 #include <unistd.h>
  34 
  35 #include "canonicalize.h"
  36 #include "error.h"
  37 #include "fatal-signal.h"
  38 #include "filename.h"
  39 #include "findprog.h"
  40 #include "unistd-safer.h"
  41 #include "wait-process.h"
  42 #include "xalloc.h"
  43 #include "gettext.h"
  44 
  45 #define _(str) gettext (str)
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 #ifndef SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
  56 # define SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN 0
  57 #endif
  58 
  59 
  60 #if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
  61 
  62 
  63 # if GNULIB_MSVC_NOTHROW
  64 #  include "msvc-nothrow.h"
  65 # else
  66 #  include <io.h>
  67 # endif
  68 # include <process.h>
  69 # include "windows-spawn.h"
  70 
  71 #elif defined __KLIBC__
  72 
  73 
  74 # include <process.h>
  75 # include "os2-spawn.h"
  76 
  77 #else
  78 
  79 
  80 # include <spawn.h>
  81 
  82 #endif
  83 
  84 
  85 #ifdef EINTR
  86 
  87 
  88 
  89 
  90 
  91 static int
  92 nonintr_close (int fd)
     
  93 {
  94   int retval;
  95 
  96   do
  97     retval = close (fd);
  98   while (retval < 0 && errno == EINTR);
  99 
 100   return retval;
 101 }
 102 #undef close 
 103 #define close nonintr_close
 104 
 105 #if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
 106 static int
 107 nonintr_open (const char *pathname, int oflag, mode_t mode)
     
 108 {
 109   int retval;
 110 
 111   do
 112     retval = open (pathname, oflag, mode);
 113   while (retval < 0 && errno == EINTR);
 114 
 115   return retval;
 116 }
 117 # undef open 
 118 # define open nonintr_open
 119 #endif
 120 
 121 #endif
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 
 136 
 137 static pid_t
 138 create_pipe (const char *progname,
     
 139              const char *prog_path,
 140              const char * const *prog_argv,
 141              const char *directory,
 142              bool pipe_stdin, bool pipe_stdout,
 143              const char *prog_stdin, const char *prog_stdout,
 144              bool null_stderr,
 145              bool slave_process, bool exit_on_error,
 146              int fd[2])
 147 {
 148   int saved_errno;
 149   char *prog_path_to_free = NULL;
 150 
 151   if (directory != NULL)
 152     {
 153       
 154 
 155 
 156 
 157 
 158 
 159 
 160 
 161 
 162 
 163 
 164 
 165 
 166 
 167       if (! IS_ABSOLUTE_FILE_NAME (prog_path))
 168         {
 169           const char *resolved_prog =
 170             find_in_given_path (prog_path, getenv ("PATH"), NULL, false);
 171           if (resolved_prog == NULL)
 172             goto fail_with_errno;
 173           if (resolved_prog != prog_path)
 174             prog_path_to_free = (char *) resolved_prog;
 175           prog_path = resolved_prog;
 176 
 177           if (! IS_ABSOLUTE_FILE_NAME (prog_path))
 178             {
 179               char *absolute_prog =
 180                 canonicalize_filename_mode (prog_path, CAN_MISSING | CAN_NOLINKS);
 181               if (absolute_prog == NULL)
 182                 {
 183                   free (prog_path_to_free);
 184                   goto fail_with_errno;
 185                 }
 186               free (prog_path_to_free);
 187               prog_path_to_free = absolute_prog;
 188               prog_path = absolute_prog;
 189 
 190               if (! IS_ABSOLUTE_FILE_NAME (prog_path))
 191                 abort ();
 192             }
 193         }
 194     }
 195 
 196 #if ((defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN) || defined __KLIBC__
 197 
 198   
 199 
 200 
 201 
 202 
 203   char *argv_mem_to_free;
 204   int ifd[2];
 205   int ofd[2];
 206   int child;
 207   int nulloutfd;
 208   int stdinfd;
 209   int stdoutfd;
 210 
 211   const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free);
 212   if (argv == NULL)
 213     xalloc_die ();
 214 
 215   if (pipe_stdout)
 216     if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
 217       error (EXIT_FAILURE, errno, _("cannot create pipe"));
 218   if (pipe_stdin)
 219     if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
 220       error (EXIT_FAILURE, errno, _("cannot create pipe"));
 221 
 222 
 223 
 224 
 225 
 226 
 227 
 228 
 229 
 230   child = -1;
 231 
 232 # if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN
 233   bool must_close_ifd1 = pipe_stdout;
 234   bool must_close_ofd0 = pipe_stdin;
 235 
 236   
 237   HANDLE stdin_handle = INVALID_HANDLE_VALUE;
 238   HANDLE stdout_handle = INVALID_HANDLE_VALUE;
 239   nulloutfd = -1;
 240   stdinfd = -1;
 241   stdoutfd = -1;
 242   if ((!null_stderr
 243        || (nulloutfd = open ("NUL", O_RDWR, 0)) >= 0)
 244       && (pipe_stdin
 245           || prog_stdin == NULL
 246           || (stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0)
 247       && (pipe_stdout
 248           || prog_stdout == NULL
 249           || (stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0))
 250     
 251 
 252     
 253 
 254 
 255 
 256 
 257 
 258 
 259     {
 260       stdin_handle =
 261         (HANDLE) _get_osfhandle (pipe_stdin ? ofd[0] :
 262                                  prog_stdin == NULL ? STDIN_FILENO : stdinfd);
 263       if (pipe_stdin)
 264         {
 265           HANDLE curr_process = GetCurrentProcess ();
 266           HANDLE duplicate;
 267           if (!DuplicateHandle (curr_process, stdin_handle,
 268                                 curr_process, &duplicate,
 269                                 0, TRUE, DUPLICATE_SAME_ACCESS))
 270             {
 271               errno = EBADF; 
 272               goto failed;
 273             }
 274           must_close_ofd0 = false;
 275           close (ofd[0]); 
 276           stdin_handle = duplicate;
 277         }
 278       stdout_handle =
 279         (HANDLE) _get_osfhandle (pipe_stdout ? ifd[1] :
 280                                  prog_stdout == NULL ? STDOUT_FILENO : stdoutfd);
 281       if (pipe_stdout)
 282         {
 283           HANDLE curr_process = GetCurrentProcess ();
 284           HANDLE duplicate;
 285           if (!DuplicateHandle (curr_process, stdout_handle,
 286                                 curr_process, &duplicate,
 287                                 0, TRUE, DUPLICATE_SAME_ACCESS))
 288             {
 289               errno = EBADF; 
 290               goto failed;
 291             }
 292           must_close_ifd1 = false;
 293           close (ifd[1]); 
 294           stdout_handle = duplicate;
 295         }
 296       HANDLE stderr_handle =
 297         (HANDLE) _get_osfhandle (null_stderr ? nulloutfd : STDERR_FILENO);
 298 
 299       child = spawnpvech (P_NOWAIT, prog_path, argv + 1,
 300                           (const char * const *) environ, directory,
 301                           stdin_handle, stdout_handle, stderr_handle);
 302 #  if 0 
 303       if (child == -1 && errno == ENOEXEC)
 304         {
 305           
 306 
 307 
 308           argv[1] = prog_path;
 309           child = spawnpvech (P_NOWAIT, argv[0], argv,
 310                               (const char * const *) environ, directory,
 311                               stdin_handle, stdout_handle, stderr_handle);
 312         }
 313 #  endif
 314     }
 315  failed:
 316   if (child == -1)
 317     saved_errno = errno;
 318   if (stdinfd >= 0)
 319     close (stdinfd);
 320   if (stdoutfd >= 0)
 321     close (stdoutfd);
 322   if (nulloutfd >= 0)
 323     close (nulloutfd);
 324 
 325   if (pipe_stdin)
 326     {
 327       if (must_close_ofd0)
 328         close (ofd[0]);
 329       else
 330         if (stdin_handle != INVALID_HANDLE_VALUE)
 331           CloseHandle (stdin_handle);
 332     }
 333   if (pipe_stdout)
 334     {
 335       if (must_close_ifd1)
 336         close (ifd[1]);
 337       else
 338         if (stdout_handle != INVALID_HANDLE_VALUE)
 339           CloseHandle (stdout_handle);
 340     }
 341 
 342 # else 
 343   if (!(directory == NULL || strcmp (directory, ".") == 0))
 344     {
 345       
 346       saved_errno = EINVAL;
 347       goto fail_with_saved_errno;
 348     }
 349 
 350   int orig_stdin;
 351   int orig_stdout;
 352   int orig_stderr;
 353 
 354   
 355   if (pipe_stdin || prog_stdin != NULL)
 356     orig_stdin = dup_safer_noinherit (STDIN_FILENO);
 357   if (pipe_stdout || prog_stdout != NULL)
 358     orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
 359   if (null_stderr)
 360     orig_stderr = dup_safer_noinherit (STDERR_FILENO);
 361 
 362   
 363   nulloutfd = -1;
 364   stdinfd = -1;
 365   stdoutfd = -1;
 366   if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
 367       && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
 368       && (!null_stderr
 369           || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
 370               && (nulloutfd == STDERR_FILENO
 371                   || (dup2 (nulloutfd, STDERR_FILENO) >= 0
 372                       && close (nulloutfd) >= 0))))
 373       && (pipe_stdin
 374           || prog_stdin == NULL
 375           || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
 376               && (stdinfd == STDIN_FILENO
 377                   || (dup2 (stdinfd, STDIN_FILENO) >= 0
 378                       && close (stdinfd) >= 0))))
 379       && (pipe_stdout
 380           || prog_stdout == NULL
 381           || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
 382               && (stdoutfd == STDOUT_FILENO
 383                   || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
 384                       && close (stdoutfd) >= 0)))))
 385     
 386 
 387 
 388     {
 389       child = _spawnvpe (P_NOWAIT, prog_path, argv + 1,
 390                          (const char **) environ);
 391 #  if 0 
 392       if (child == -1 && errno == ENOEXEC)
 393         {
 394           
 395 
 396 
 397           child = _spawnvpe (P_NOWAIT, argv[0], argv,
 398                              (const char **) environ);
 399         }
 400 #  endif
 401     }
 402   if (child == -1)
 403     saved_errno = errno;
 404   if (stdinfd >= 0)
 405     close (stdinfd);
 406   if (stdoutfd >= 0)
 407     close (stdoutfd);
 408   if (nulloutfd >= 0)
 409     close (nulloutfd);
 410 
 411   
 412   if (null_stderr)
 413     undup_safer_noinherit (orig_stderr, STDERR_FILENO);
 414   if (pipe_stdout || prog_stdout != NULL)
 415     undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
 416   if (pipe_stdin || prog_stdin != NULL)
 417     undup_safer_noinherit (orig_stdin, STDIN_FILENO);
 418 
 419   if (pipe_stdin)
 420     close (ofd[0]);
 421   if (pipe_stdout)
 422     close (ifd[1]);
 423 # endif
 424 
 425   free (argv);
 426   free (argv_mem_to_free);
 427   free (prog_path_to_free);
 428 
 429   if (child == -1)
 430     {
 431       if (pipe_stdout)
 432         close (ifd[0]);
 433       if (pipe_stdin)
 434         close (ofd[1]);
 435       goto fail_with_saved_errno;
 436     }
 437 
 438   if (pipe_stdout)
 439     fd[0] = ifd[0];
 440   if (pipe_stdin)
 441     fd[1] = ofd[1];
 442   return child;
 443 
 444 #else
 445 
 446   
 447   int ifd[2];
 448   int ofd[2];
 449   sigset_t blocked_signals;
 450   posix_spawn_file_actions_t actions;
 451   bool actions_allocated;
 452   posix_spawnattr_t attrs;
 453   bool attrs_allocated;
 454   int err;
 455   pid_t child;
 456 
 457   if (pipe_stdout)
 458     if (pipe_safer (ifd) < 0)
 459       error (EXIT_FAILURE, errno, _("cannot create pipe"));
 460   if (pipe_stdin)
 461     if (pipe_safer (ofd) < 0)
 462       error (EXIT_FAILURE, errno, _("cannot create pipe"));
 463 
 464 
 465 
 466 
 467 
 468 
 469 
 470 
 471 
 472   if (slave_process)
 473     {
 474       sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
 475       block_fatal_signals ();
 476     }
 477   actions_allocated = false;
 478   attrs_allocated = false;
 479   if ((err = posix_spawn_file_actions_init (&actions)) != 0
 480       || (actions_allocated = true,
 481           (pipe_stdin
 482            && (err = posix_spawn_file_actions_adddup2 (&actions,
 483                                                        ofd[0], STDIN_FILENO))
 484               != 0)
 485           || (pipe_stdout
 486               && (err = posix_spawn_file_actions_adddup2 (&actions,
 487                                                           ifd[1], STDOUT_FILENO))
 488                  != 0)
 489           || (pipe_stdin
 490               && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
 491                  != 0)
 492           || (pipe_stdout
 493               && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
 494                  != 0)
 495           || (pipe_stdin
 496               && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
 497                  != 0)
 498           || (pipe_stdout
 499               && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
 500                  != 0)
 501           || (null_stderr
 502               && (err = posix_spawn_file_actions_addopen (&actions,
 503                                                           STDERR_FILENO,
 504                                                           "/dev/null", O_RDWR,
 505                                                           0))
 506                  != 0)
 507           || (!pipe_stdin
 508               && prog_stdin != NULL
 509               && (err = posix_spawn_file_actions_addopen (&actions,
 510                                                           STDIN_FILENO,
 511                                                           prog_stdin, O_RDONLY,
 512                                                           0))
 513                  != 0)
 514           || (!pipe_stdout
 515               && prog_stdout != NULL
 516               && (err = posix_spawn_file_actions_addopen (&actions,
 517                                                           STDOUT_FILENO,
 518                                                           prog_stdout, O_WRONLY,
 519                                                           0))
 520                  != 0)
 521           || (directory != NULL
 522               && (err = posix_spawn_file_actions_addchdir (&actions,
 523                                                            directory)))
 524           || (slave_process
 525               && ((err = posix_spawnattr_init (&attrs)) != 0
 526                   || (attrs_allocated = true,
 527 # if defined _WIN32 && !defined __CYGWIN__
 528                       (err = posix_spawnattr_setpgroup (&attrs, 0)) != 0
 529                       || (err = posix_spawnattr_setflags (&attrs,
 530                                                          POSIX_SPAWN_SETPGROUP))
 531                          != 0
 532 # else
 533                       (err = posix_spawnattr_setsigmask (&attrs,
 534                                                          &blocked_signals))
 535                       != 0
 536                       || (err = posix_spawnattr_setflags (&attrs,
 537                                                         POSIX_SPAWN_SETSIGMASK))
 538                          != 0
 539 # endif
 540              )   )   )
 541           || (err = (directory != NULL
 542                      ? posix_spawn (&child, prog_path, &actions,
 543                                     attrs_allocated ? &attrs : NULL,
 544                                     (char * const *) prog_argv, environ)
 545                      : posix_spawnp (&child, prog_path, &actions,
 546                                      attrs_allocated ? &attrs : NULL,
 547                                      (char * const *) prog_argv, environ)))
 548              != 0))
 549     {
 550       if (actions_allocated)
 551         posix_spawn_file_actions_destroy (&actions);
 552       if (attrs_allocated)
 553         posix_spawnattr_destroy (&attrs);
 554       if (slave_process)
 555         unblock_fatal_signals ();
 556       if (pipe_stdout)
 557         {
 558           close (ifd[0]);
 559           close (ifd[1]);
 560         }
 561       if (pipe_stdin)
 562         {
 563           close (ofd[0]);
 564           close (ofd[1]);
 565         }
 566       free (prog_path_to_free);
 567       saved_errno = err;
 568       goto fail_with_saved_errno;
 569     }
 570   posix_spawn_file_actions_destroy (&actions);
 571   if (attrs_allocated)
 572     posix_spawnattr_destroy (&attrs);
 573   if (slave_process)
 574     {
 575       register_slave_subprocess (child);
 576       unblock_fatal_signals ();
 577     }
 578   if (pipe_stdin)
 579     close (ofd[0]);
 580   if (pipe_stdout)
 581     close (ifd[1]);
 582   free (prog_path_to_free);
 583 
 584   if (pipe_stdout)
 585     fd[0] = ifd[0];
 586   if (pipe_stdin)
 587     fd[1] = ofd[1];
 588   return child;
 589 
 590 #endif
 591 
 592  fail_with_errno:
 593   saved_errno = errno;
 594  fail_with_saved_errno:
 595   if (exit_on_error || !null_stderr)
 596     error (exit_on_error ? EXIT_FAILURE : 0, saved_errno,
 597            _("%s subprocess failed"), progname);
 598   errno = saved_errno;
 599   return -1;
 600 }
 601 
 602 
 603 
 604 
 605 
 606 
 607 
 608 
 609 
 610 pid_t
 611 create_pipe_bidi (const char *progname,
     
 612                   const char *prog_path, const char * const *prog_argv,
 613                   const char *directory,
 614                   bool null_stderr,
 615                   bool slave_process, bool exit_on_error,
 616                   int fd[2])
 617 {
 618   pid_t result = create_pipe (progname, prog_path, prog_argv, directory,
 619                               true, true, NULL, NULL,
 620                               null_stderr, slave_process, exit_on_error,
 621                               fd);
 622   return result;
 623 }
 624 
 625 
 626 
 627 
 628 
 629 
 630 
 631 
 632 pid_t
 633 create_pipe_in (const char *progname,
     
 634                 const char *prog_path, const char * const *prog_argv,
 635                 const char *directory,
 636                 const char *prog_stdin, bool null_stderr,
 637                 bool slave_process, bool exit_on_error,
 638                 int fd[1])
 639 {
 640   int iofd[2];
 641   pid_t result = create_pipe (progname, prog_path, prog_argv, directory,
 642                               false, true, prog_stdin, NULL,
 643                               null_stderr, slave_process, exit_on_error,
 644                               iofd);
 645   if (result != -1)
 646     fd[0] = iofd[0];
 647   return result;
 648 }
 649 
 650 
 651 
 652 
 653 
 654 
 655 
 656 
 657 pid_t
 658 create_pipe_out (const char *progname,
     
 659                  const char *prog_path, const char * const *prog_argv,
 660                  const char *directory,
 661                  const char *prog_stdout, bool null_stderr,
 662                  bool slave_process, bool exit_on_error,
 663                  int fd[1])
 664 {
 665   int iofd[2];
 666   pid_t result = create_pipe (progname, prog_path, prog_argv, directory,
 667                               true, false, NULL, prog_stdout,
 668                               null_stderr, slave_process, exit_on_error,
 669                               iofd);
 670   if (result != -1)
 671     fd[0] = iofd[1];
 672   return result;
 673 }