Home | History | Annotate | Line # | Download | only in libiberty
      1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
      2    with other subprocesses), and wait for it.  Generic Unix version
      3    (also used for UWIN and VMS).
      4    Copyright (C) 1996-2024 Free Software Foundation, Inc.
      5 
      6 This file is part of the libiberty library.
      7 Libiberty is free software; you can redistribute it and/or
      8 modify it under the terms of the GNU Library General Public
      9 License as published by the Free Software Foundation; either
     10 version 2 of the License, or (at your option) any later version.
     11 
     12 Libiberty is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 Library General Public License for more details.
     16 
     17 You should have received a copy of the GNU Library General Public
     18 License along with libiberty; see the file COPYING.LIB.  If not,
     19 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     20 Boston, MA 02110-1301, USA.  */
     21 
     22 #include "config.h"
     23 #include "libiberty.h"
     24 #include "pex-common.h"
     25 #include "environ.h"
     26 
     27 #include <stdio.h>
     28 #include <signal.h>
     29 #include <errno.h>
     30 #ifdef NEED_DECLARATION_ERRNO
     31 extern int errno;
     32 #endif
     33 #ifdef HAVE_STDLIB_H
     34 #include <stdlib.h>
     35 #endif
     36 #ifdef HAVE_STRING_H
     37 #include <string.h>
     38 #endif
     39 #ifdef HAVE_UNISTD_H
     40 #include <unistd.h>
     41 #endif
     42 
     43 #include <sys/types.h>
     44 
     45 #ifdef HAVE_FCNTL_H
     46 #include <fcntl.h>
     47 #endif
     48 #ifdef HAVE_SYS_WAIT_H
     49 #include <sys/wait.h>
     50 #endif
     51 #ifdef HAVE_GETRUSAGE
     52 #include <sys/time.h>
     53 #include <sys/resource.h>
     54 #endif
     55 #ifdef HAVE_SYS_STAT_H
     56 #include <sys/stat.h>
     57 #endif
     58 #ifdef HAVE_PROCESS_H
     59 #include <process.h>
     60 #endif
     61 #ifdef HAVE_SPAWN_H
     62 #include <spawn.h>
     63 #endif
     64 
     65 #ifdef vfork /* Autoconf may define this to fork for us. */
     66 # define VFORK_STRING "fork"
     67 #else
     68 # define VFORK_STRING "vfork"
     69 #endif
     70 #ifdef HAVE_VFORK_H
     71 #include <vfork.h>
     72 #endif
     73 #if defined(VMS) && defined (__LONG_POINTERS)
     74 #ifndef __CHAR_PTR32
     75 typedef char * __char_ptr32
     76 __attribute__ ((mode (SI)));
     77 #endif
     78 
     79 typedef __char_ptr32 *__char_ptr_char_ptr32
     80 __attribute__ ((mode (SI)));
     81 
     82 /* Return a 32 bit pointer to an array of 32 bit pointers
     83    given a 64 bit pointer to an array of 64 bit pointers.  */
     84 
     85 static __char_ptr_char_ptr32
     86 to_ptr32 (char **ptr64)
     87 {
     88   int argc;
     89   __char_ptr_char_ptr32 short_argv;
     90 
     91   /* Count number of arguments.  */
     92   for (argc = 0; ptr64[argc] != NULL; argc++)
     93     ;
     94 
     95   /* Reallocate argv with 32 bit pointers.  */
     96   short_argv = (__char_ptr_char_ptr32) decc$malloc
     97     (sizeof (__char_ptr32) * (argc + 1));
     98 
     99   for (argc = 0; ptr64[argc] != NULL; argc++)
    100     short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
    101 
    102   short_argv[argc] = (__char_ptr32) 0;
    103   return short_argv;
    104 
    105 }
    106 #else
    107 #define to_ptr32(argv) argv
    108 #endif
    109 
    110 /* File mode to use for private and world-readable files.  */
    111 
    112 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
    113 #define PUBLIC_MODE  \
    114     (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
    115 #else
    116 #define PUBLIC_MODE 0666
    117 #endif
    118 
    119 /* Get the exit status of a particular process, and optionally get the
    120    time that it took.  This is simple if we have wait4, slightly
    121    harder if we have waitpid, and is a pain if we only have wait.  */
    122 
    123 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
    124 
    125 #ifdef HAVE_WAIT4
    126 
    127 static pid_t
    128 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    129 	  struct pex_time *time)
    130 {
    131   pid_t ret;
    132   struct rusage r;
    133 
    134 #ifdef HAVE_WAITPID
    135   if (time == NULL)
    136     return waitpid (pid, status, 0);
    137 #endif
    138 
    139   ret = wait4 (pid, status, 0, &r);
    140 
    141   if (time != NULL)
    142     {
    143       time->user_seconds = r.ru_utime.tv_sec;
    144       time->user_microseconds= r.ru_utime.tv_usec;
    145       time->system_seconds = r.ru_stime.tv_sec;
    146       time->system_microseconds= r.ru_stime.tv_usec;
    147     }
    148 
    149   return ret;
    150 }
    151 
    152 #else /* ! defined (HAVE_WAIT4) */
    153 
    154 #ifdef HAVE_WAITPID
    155 
    156 #ifndef HAVE_GETRUSAGE
    157 
    158 static pid_t
    159 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    160 	  struct pex_time *time)
    161 {
    162   if (time != NULL)
    163     memset (time, 0, sizeof (struct pex_time));
    164   return waitpid (pid, status, 0);
    165 }
    166 
    167 #else /* defined (HAVE_GETRUSAGE) */
    168 
    169 static pid_t
    170 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    171 	  struct pex_time *time)
    172 {
    173   struct rusage r1, r2;
    174   pid_t ret;
    175 
    176   if (time == NULL)
    177     return waitpid (pid, status, 0);
    178 
    179   getrusage (RUSAGE_CHILDREN, &r1);
    180 
    181   ret = waitpid (pid, status, 0);
    182   if (ret < 0)
    183     return ret;
    184 
    185   getrusage (RUSAGE_CHILDREN, &r2);
    186 
    187   time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
    188   time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
    189   if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
    190     {
    191       --time->user_seconds;
    192       time->user_microseconds += 1000000;
    193     }
    194 
    195   time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
    196   time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
    197   if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
    198     {
    199       --time->system_seconds;
    200       time->system_microseconds += 1000000;
    201     }
    202 
    203   return ret;
    204 }
    205 
    206 #endif /* defined (HAVE_GETRUSAGE) */
    207 
    208 #else /* ! defined (HAVE_WAITPID) */
    209 
    210 struct status_list
    211 {
    212   struct status_list *next;
    213   pid_t pid;
    214   int status;
    215   struct pex_time time;
    216 };
    217 
    218 static pid_t
    219 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
    220 {
    221   struct status_list **pp;
    222 
    223   for (pp = (struct status_list **) &obj->sysdep;
    224        *pp != NULL;
    225        pp = &(*pp)->next)
    226     {
    227       if ((*pp)->pid == pid)
    228 	{
    229 	  struct status_list *p;
    230 
    231 	  p = *pp;
    232 	  *status = p->status;
    233 	  if (time != NULL)
    234 	    *time = p->time;
    235 	  *pp = p->next;
    236 	  free (p);
    237 	  return pid;
    238 	}
    239     }
    240 
    241   while (1)
    242     {
    243       pid_t cpid;
    244       struct status_list *psl;
    245       struct pex_time pt;
    246 #ifdef HAVE_GETRUSAGE
    247       struct rusage r1, r2;
    248 #endif
    249 
    250       if (time != NULL)
    251 	{
    252 #ifdef HAVE_GETRUSAGE
    253 	  getrusage (RUSAGE_CHILDREN, &r1);
    254 #else
    255 	  memset (&pt, 0, sizeof (struct pex_time));
    256 #endif
    257 	}
    258 
    259       cpid = wait (status);
    260 
    261 #ifdef HAVE_GETRUSAGE
    262       if (time != NULL && cpid >= 0)
    263 	{
    264 	  getrusage (RUSAGE_CHILDREN, &r2);
    265 
    266 	  pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
    267 	  pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
    268 	  if (pt.user_microseconds < 0)
    269 	    {
    270 	      --pt.user_seconds;
    271 	      pt.user_microseconds += 1000000;
    272 	    }
    273 
    274 	  pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
    275 	  pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
    276 	  if (pt.system_microseconds < 0)
    277 	    {
    278 	      --pt.system_seconds;
    279 	      pt.system_microseconds += 1000000;
    280 	    }
    281 	}
    282 #endif
    283 
    284       if (cpid < 0 || cpid == pid)
    285 	{
    286 	  if (time != NULL)
    287 	    *time = pt;
    288 	  return cpid;
    289 	}
    290 
    291       psl = XNEW (struct status_list);
    292       psl->pid = cpid;
    293       psl->status = *status;
    294       if (time != NULL)
    295 	psl->time = pt;
    296       psl->next = (struct status_list *) obj->sysdep;
    297       obj->sysdep = (void *) psl;
    298     }
    299 }
    300 
    301 #endif /* ! defined (HAVE_WAITPID) */
    302 #endif /* ! defined (HAVE_WAIT4) */
    303 
    304 static int pex_unix_open_read (struct pex_obj *, const char *, int);
    305 static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
    306 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
    307 				 char * const *, char * const *,
    308 				 int, int, int, int,
    309 				 const char **, int *);
    310 static int pex_unix_close (struct pex_obj *, int);
    311 static pid_t pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
    312 			   int, const char **, int *);
    313 static int pex_unix_pipe (struct pex_obj *, int *, int);
    314 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
    315 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
    316 static void pex_unix_cleanup (struct pex_obj *);
    317 
    318 /* The list of functions we pass to the common routines.  */
    319 
    320 const struct pex_funcs funcs =
    321 {
    322   pex_unix_open_read,
    323   pex_unix_open_write,
    324   pex_unix_exec_child,
    325   pex_unix_close,
    326   pex_unix_wait,
    327   pex_unix_pipe,
    328   pex_unix_fdopenr,
    329   pex_unix_fdopenw,
    330   pex_unix_cleanup
    331 };
    332 
    333 /* Return a newly initialized pex_obj structure.  */
    334 
    335 struct pex_obj *
    336 pex_init (int flags, const char *pname, const char *tempbase)
    337 {
    338   return pex_init_common (flags, pname, tempbase, &funcs);
    339 }
    340 
    341 /* Open a file for reading.  */
    342 
    343 static int
    344 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
    345 		    int binary ATTRIBUTE_UNUSED)
    346 {
    347   return open (name, O_RDONLY);
    348 }
    349 
    350 /* Open a file for writing.  */
    351 
    352 static int
    353 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
    354 		     int binary ATTRIBUTE_UNUSED, int append)
    355 {
    356   /* Note that we can't use O_EXCL here because gcc may have already
    357      created the temporary file via make_temp_file.  */
    358   return open (name, O_WRONLY | O_CREAT
    359 		     | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE);
    360 }
    361 
    362 /* Close a file.  */
    363 
    364 static int
    365 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
    366 {
    367   return close (fd);
    368 }
    369 
    370 /* Execute a child.  */
    371 
    372 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
    373 /* Implementation of pex->exec_child using the Cygwin spawn operation.  */
    374 
    375 /* Subroutine of pex_unix_exec_child.  Move OLD_FD to a new file descriptor
    376    to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the
    377    saved copy to be close-on-exec.  Move CHILD_FD into OLD_FD.  If CHILD_FD
    378    is -1, OLD_FD is to be closed.  Return -1 on error.  */
    379 
    380 static int
    381 save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd)
    382 {
    383   int new_fd, flags;
    384 
    385   flags = fcntl (old_fd, F_GETFD);
    386 
    387   /* If we could not retrieve the flags, then OLD_FD was not open.  */
    388   if (flags < 0)
    389     {
    390       new_fd = -1, flags = 0;
    391       if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0)
    392 	return -1;
    393     }
    394   /* If we wish to close OLD_FD, just mark it CLOEXEC.  */
    395   else if (child_fd == -1)
    396     {
    397       new_fd = old_fd;
    398       if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0)
    399 	return -1;
    400     }
    401   /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD.  */
    402   else
    403     {
    404 #ifdef F_DUPFD_CLOEXEC
    405       new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3);
    406       if (new_fd < 0)
    407 	return -1;
    408 #else
    409       /* Prefer F_DUPFD over dup in order to avoid getting a new fd
    410 	 in the range 0-2, right where a new stderr fd might get put.  */
    411       new_fd = fcntl (old_fd, F_DUPFD, 3);
    412       if (new_fd < 0)
    413 	return -1;
    414       if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0)
    415 	return -1;
    416 #endif
    417       if (dup2 (child_fd, old_fd) < 0)
    418 	return -1;
    419     }
    420 
    421   *pflags = flags;
    422   if (pnew_fd)
    423     *pnew_fd = new_fd;
    424   else if (new_fd != old_fd)
    425     abort ();
    426 
    427   return 0;
    428 }
    429 
    430 /* Subroutine of pex_unix_exec_child.  Move SAVE_FD back to OLD_FD
    431    restoring FLAGS.  If SAVE_FD < 0, OLD_FD is to be closed.  */
    432 
    433 static int
    434 restore_fd(int old_fd, int save_fd, int flags)
    435 {
    436   /* For SAVE_FD < 0, all we have to do is restore the
    437      "closed-ness" of the original.  */
    438   if (save_fd < 0)
    439     return close (old_fd);
    440 
    441   /* For SAVE_FD == OLD_FD, all we have to do is restore the
    442      original setting of the CLOEXEC flag.  */
    443   if (save_fd == old_fd)
    444     {
    445       if (flags & FD_CLOEXEC)
    446 	return 0;
    447       return fcntl (old_fd, F_SETFD, flags);
    448     }
    449 
    450   /* Otherwise we have to move the descriptor back, restore the flags,
    451      and close the saved copy.  */
    452 #ifdef HAVE_DUP3
    453   if (flags == FD_CLOEXEC)
    454     {
    455       if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0)
    456 	return -1;
    457     }
    458   else
    459 #endif
    460     {
    461       if (dup2 (save_fd, old_fd) < 0)
    462 	return -1;
    463       if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0)
    464 	return -1;
    465     }
    466   return close (save_fd);
    467 }
    468 
    469 static pid_t
    470 pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED,
    471 		     int flags, const char *executable,
    472 		     char * const * argv, char * const * env,
    473                      int in, int out, int errdes, int toclose,
    474 		     const char **errmsg, int *err)
    475 {
    476   int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0;
    477   int save_in = -1, save_out = -1, save_err = -1;
    478   int max, retries;
    479   pid_t pid;
    480 
    481   if (flags & PEX_STDERR_TO_STDOUT)
    482     errdes = out;
    483 
    484   /* We need the three standard file descriptors to be set up as for
    485      the child before we perform the spawn.  The file descriptors for
    486      the parent need to be moved and marked for close-on-exec.  */
    487   if (in != STDIN_FILE_NO
    488       && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0)
    489     goto error_dup2;
    490   if (out != STDOUT_FILE_NO
    491       && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0)
    492     goto error_dup2;
    493   if (errdes != STDERR_FILE_NO
    494       && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0)
    495     goto error_dup2;
    496   if (toclose >= 0
    497       && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0)
    498     goto error_dup2;
    499 
    500   /* Now that we've moved the file descriptors for the child into place,
    501      close the originals.  Be careful not to close any of the standard
    502      file descriptors that we just set up.  */
    503   max = -1;
    504   if (errdes >= 0)
    505     max = STDERR_FILE_NO;
    506   else if (out >= 0)
    507     max = STDOUT_FILE_NO;
    508   else if (in >= 0)
    509     max = STDIN_FILE_NO;
    510   if (in > max)
    511     close (in);
    512   if (out > max)
    513     close (out);
    514   if (errdes > max && errdes != out)
    515     close (errdes);
    516 
    517   /* If we were not given an environment, use the global environment.  */
    518   if (env == NULL)
    519     env = environ;
    520 
    521   /* Launch the program.  If we get EAGAIN (normally out of pid's), try
    522      again a few times with increasing backoff times.  */
    523   retries = 0;
    524   while (1)
    525     {
    526       typedef const char * const *cc_cp;
    527 
    528       if (flags & PEX_SEARCH)
    529 	pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
    530       else
    531 	pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
    532 
    533       if (pid > 0)
    534 	break;
    535 
    536       *err = errno;
    537       *errmsg = "spawn";
    538       if (errno != EAGAIN || ++retries == 4)
    539 	return (pid_t) -1;
    540       sleep (1 << retries);
    541     }
    542 
    543   /* Success.  Restore the parent's file descriptors that we saved above.  */
    544   if (toclose >= 0
    545       && restore_fd (toclose, toclose, fl_tc) < 0)
    546     goto error_dup2;
    547   if (in != STDIN_FILE_NO
    548       && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0)
    549     goto error_dup2;
    550   if (out != STDOUT_FILE_NO
    551       && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0)
    552     goto error_dup2;
    553   if (errdes != STDERR_FILE_NO
    554       && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0)
    555     goto error_dup2;
    556 
    557   return pid;
    558 
    559  error_dup2:
    560   *err = errno;
    561   *errmsg = "dup2";
    562   return (pid_t) -1;
    563 }
    564 
    565 #elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP)
    566 /* Implementation of pex->exec_child using posix_spawn.            */
    567 
    568 static pid_t
    569 pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED,
    570 		     int flags, const char *executable,
    571 		     char * const * argv, char * const * env,
    572 		     int in, int out, int errdes,
    573 		     int toclose, const char **errmsg, int *err)
    574 {
    575   int ret;
    576   pid_t pid = -1;
    577   posix_spawnattr_t attr;
    578   posix_spawn_file_actions_t actions;
    579   int attr_initialized = 0, actions_initialized = 0;
    580 
    581   *err = 0;
    582 
    583   ret = posix_spawnattr_init (&attr);
    584   if (ret)
    585     {
    586       *err = ret;
    587       *errmsg = "posix_spawnattr_init";
    588       goto exit;
    589     }
    590   attr_initialized = 1;
    591 
    592   /* Use vfork() on glibc <=2.24. */
    593 #ifdef POSIX_SPAWN_USEVFORK
    594   ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK);
    595   if (ret)
    596     {
    597       *err = ret;
    598       *errmsg = "posix_spawnattr_setflags";
    599       goto exit;
    600     }
    601 #endif
    602 
    603   ret = posix_spawn_file_actions_init (&actions);
    604   if (ret)
    605     {
    606       *err = ret;
    607       *errmsg = "posix_spawn_file_actions_init";
    608       goto exit;
    609     }
    610   actions_initialized = 1;
    611 
    612   if (in != STDIN_FILE_NO)
    613     {
    614       ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO);
    615       if (ret)
    616 	{
    617 	  *err = ret;
    618 	  *errmsg = "posix_spawn_file_actions_adddup2";
    619 	  goto exit;
    620 	}
    621 
    622       ret = posix_spawn_file_actions_addclose (&actions, in);
    623       if (ret)
    624 	{
    625 	  *err = ret;
    626 	  *errmsg = "posix_spawn_file_actions_addclose";
    627 	  goto exit;
    628 	}
    629     }
    630 
    631   if (out != STDOUT_FILE_NO)
    632     {
    633       ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO);
    634       if (ret)
    635 	{
    636 	  *err = ret;
    637 	  *errmsg = "posix_spawn_file_actions_adddup2";
    638 	  goto exit;
    639 	}
    640 
    641       ret = posix_spawn_file_actions_addclose (&actions, out);
    642       if (ret)
    643 	{
    644 	  *err = ret;
    645 	  *errmsg = "posix_spawn_file_actions_addclose";
    646 	  goto exit;
    647 	}
    648     }
    649 
    650   if (errdes != STDERR_FILE_NO)
    651     {
    652       ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO);
    653       if (ret)
    654 	{
    655 	  *err = ret;
    656 	  *errmsg = "posix_spawn_file_actions_adddup2";
    657 	  goto exit;
    658 	}
    659 
    660       ret = posix_spawn_file_actions_addclose (&actions, errdes);
    661       if (ret)
    662 	{
    663 	  *err = ret;
    664 	  *errmsg = "posix_spawn_file_actions_addclose";
    665 	  goto exit;
    666 	}
    667     }
    668 
    669   if (toclose >= 0)
    670     {
    671       ret = posix_spawn_file_actions_addclose (&actions, toclose);
    672       if (ret)
    673 	{
    674 	  *err = ret;
    675 	  *errmsg = "posix_spawn_file_actions_addclose";
    676 	  goto exit;
    677 	}
    678     }
    679 
    680   if ((flags & PEX_STDERR_TO_STDOUT) != 0)
    681     {
    682       ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO);
    683       if (ret)
    684 	{
    685 	  *err = ret;
    686 	  *errmsg = "posix_spawn_file_actions_adddup2";
    687 	  goto exit;
    688 	}
    689     }
    690 
    691   if ((flags & PEX_SEARCH) != 0)
    692     {
    693       ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ);
    694       if (ret)
    695 	{
    696 	  *err = ret;
    697 	  *errmsg = "posix_spawnp";
    698 	  pid = -1; /* The value of pid is unspecified on failure.  */
    699 	  goto exit;
    700 	}
    701     }
    702   else
    703     {
    704       ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ);
    705       if (ret)
    706 	{
    707 	  *err = ret;
    708 	  *errmsg = "posix_spawn";
    709 	  pid = -1;
    710 	  goto exit;
    711 	}
    712     }
    713 
    714 exit:
    715   if (actions_initialized)
    716     posix_spawn_file_actions_destroy (&actions);
    717   if (attr_initialized)
    718     posix_spawnattr_destroy (&attr);
    719 
    720   if (!*err && in != STDIN_FILE_NO)
    721     if (close (in))
    722       *errmsg = "close", *err = errno, pid = -1;
    723   if (!*err && out != STDOUT_FILE_NO)
    724     if (close (out))
    725       *errmsg = "close", *err = errno, pid = -1;
    726   if (!*err && errdes != STDERR_FILE_NO)
    727     if (close (errdes))
    728       *errmsg = "close", *err = errno, pid = -1;
    729 
    730   return pid;
    731 }
    732 #else
    733 /* Implementation of pex->exec_child using standard vfork + exec.  */
    734 
    735 static pid_t
    736 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
    737 		     char * const * argv, char * const * env,
    738                      int in, int out, int errdes,
    739 		     int toclose, const char **errmsg, int *err)
    740 {
    741   pid_t pid = -1;
    742   /* Tuple to communicate error from child to parent.  We can safely
    743      transfer string literal pointers as both run with identical
    744      address mappings.  */
    745   struct fn_err
    746   {
    747     const char *fn;
    748     int err;
    749   };
    750   volatile int do_pipe = 0;
    751   volatile int pipes[2]; /* [0]:reader,[1]:writer.  */
    752 #ifdef O_CLOEXEC
    753   do_pipe = 1;
    754 #endif
    755   if (do_pipe)
    756     {
    757 #ifdef HAVE_PIPE2
    758       if (pipe2 ((int *)pipes, O_CLOEXEC))
    759 	do_pipe = 0;
    760 #else
    761       if (pipe ((int *)pipes))
    762 	do_pipe = 0;
    763       else
    764 	{
    765 	  if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1)
    766 	    {
    767 	      close (pipes[0]);
    768 	      close (pipes[1]);
    769 	      do_pipe = 0;
    770 	    }
    771 	}
    772 #endif
    773     }
    774 
    775   /* We declare these to be volatile to avoid warnings from gcc about
    776      them being clobbered by vfork.  */
    777   volatile int sleep_interval = 1;
    778   volatile int retries;
    779 
    780   /* We vfork and then set environ in the child before calling execvp.
    781      This clobbers the parent's environ so we need to restore it.
    782      It would be nice to use one of the exec* functions that takes an
    783      environment as a parameter, but that may have portability
    784      issues.  It is marked volatile so the child doesn't consider it a
    785      dead variable and therefore clobber where ever it is stored.  */
    786   char **volatile save_environ = environ;
    787 
    788   for (retries = 0; retries < 4; ++retries)
    789     {
    790       pid = vfork ();
    791       if (pid >= 0)
    792 	break;
    793       sleep (sleep_interval);
    794       sleep_interval *= 2;
    795     }
    796 
    797   switch (pid)
    798     {
    799     case -1:
    800       if (do_pipe)
    801 	{
    802 	  close (pipes[0]);
    803 	  close (pipes[1]);
    804 	}
    805       *err = errno;
    806       *errmsg = VFORK_STRING;
    807       return (pid_t) -1;
    808 
    809     case 0:
    810       /* Child process.  */
    811       {
    812 	struct fn_err failed;
    813 	failed.fn = NULL;
    814 
    815 	if (do_pipe)
    816 	  close (pipes[0]);
    817 	if (!failed.fn && in != STDIN_FILE_NO)
    818 	  {
    819 	    if (dup2 (in, STDIN_FILE_NO) < 0)
    820 	      failed.fn = "dup2", failed.err = errno;
    821 	    else if (close (in) < 0)
    822 	      failed.fn = "close", failed.err = errno;
    823 	  }
    824 	if (!failed.fn && out != STDOUT_FILE_NO)
    825 	  {
    826 	    if (dup2 (out, STDOUT_FILE_NO) < 0)
    827 	      failed.fn = "dup2", failed.err = errno;
    828 	    else if (close (out) < 0)
    829 	      failed.fn = "close", failed.err = errno;
    830 	  }
    831 	if (!failed.fn && errdes != STDERR_FILE_NO)
    832 	  {
    833 	    if (dup2 (errdes, STDERR_FILE_NO) < 0)
    834 	      failed.fn = "dup2", failed.err = errno;
    835 	    else if (close (errdes) < 0)
    836 	      failed.fn = "close", failed.err = errno;
    837 	  }
    838 	if (!failed.fn && toclose >= 0)
    839 	  {
    840 	    if (close (toclose) < 0)
    841 	      failed.fn = "close", failed.err = errno;
    842 	  }
    843 	if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
    844 	  {
    845 	    if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
    846 	      failed.fn = "dup2", failed.err = errno;
    847 	  }
    848 	if (!failed.fn)
    849 	  {
    850 	    if (env)
    851 	      /* NOTE: In a standard vfork implementation this clobbers
    852 		 the parent's copy of environ "too" (in reality there's
    853 		 only one copy).  This is ok as we restore it below.  */
    854 	      environ = (char**) env;
    855 	    if ((flags & PEX_SEARCH) != 0)
    856 	      {
    857 		execvp (executable, to_ptr32 (argv));
    858 		failed.fn = "execvp", failed.err = errno;
    859 	      }
    860 	    else
    861 	      {
    862 		execv (executable, to_ptr32 (argv));
    863 		failed.fn = "execv", failed.err = errno;
    864 	      }
    865 	  }
    866 
    867 	/* Something failed, report an error.  We don't use stdio
    868 	   routines, because we might be here due to a vfork call.  */
    869 	ssize_t retval = 0;
    870 
    871 	if (!do_pipe
    872 	    || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed))
    873 	  {
    874 	    /* The parent will not see our scream above, so write to
    875 	       stdout.  */
    876 #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
    877 	    writeerr (obj->pname);
    878 	    writeerr (": error trying to exec '");
    879 	    writeerr (executable);
    880 	    writeerr ("': ");
    881 	    writeerr (failed.fn);
    882 	    writeerr (": ");
    883 	    writeerr (xstrerror (failed.err));
    884 	    writeerr ("\n");
    885 #undef writeerr
    886 	  }
    887 
    888 	/* Exit with -2 if the error output failed, too.  */
    889 	_exit (retval < 0 ? -2 : -1);
    890       }
    891       /* NOTREACHED */
    892       return (pid_t) -1;
    893 
    894     default:
    895       /* Parent process.  */
    896       {
    897 	/* Restore environ.  Note that the parent either doesn't run
    898 	   until the child execs/exits (standard vfork behaviour), or
    899 	   if it does run then vfork is behaving more like fork.  In
    900 	   either case we needn't worry about clobbering the child's
    901 	   copy of environ.  */
    902 	environ = save_environ;
    903 
    904 	struct fn_err failed;
    905 	failed.fn = NULL;
    906 	if (do_pipe)
    907 	  {
    908 	    close (pipes[1]);
    909 	    ssize_t len = read (pipes[0], &failed, sizeof (failed));
    910 	    if (len < 0)
    911 	      failed.fn = NULL;
    912 	    close (pipes[0]);
    913 	  }
    914 
    915 	if (!failed.fn && in != STDIN_FILE_NO)
    916 	  if (close (in) < 0)
    917 	    failed.fn = "close", failed.err = errno;
    918 	if (!failed.fn && out != STDOUT_FILE_NO)
    919 	  if (close (out) < 0)
    920 	    failed.fn = "close", failed.err = errno;
    921 	if (!failed.fn && errdes != STDERR_FILE_NO)
    922 	  if (close (errdes) < 0)
    923 	    failed.fn = "close", failed.err = errno;
    924 
    925 	if (failed.fn)
    926 	  {
    927 	    *err = failed.err;
    928 	    *errmsg = failed.fn;
    929 	    return (pid_t) -1;
    930 	  }
    931       }
    932       return pid;
    933     }
    934 }
    935 #endif /* SPAWN */
    936 
    937 /* Wait for a child process to complete.  */
    938 
    939 static pid_t
    940 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
    941 	       struct pex_time *time, int done, const char **errmsg,
    942 	       int *err)
    943 {
    944   /* If we are cleaning up when the caller didn't retrieve process
    945      status for some reason, encourage the process to go away.  */
    946   if (done)
    947     kill (pid, SIGTERM);
    948 
    949   if (pex_wait (obj, pid, status, time) < 0)
    950     {
    951       *err = errno;
    952       *errmsg = "wait";
    953       return -1;
    954     }
    955 
    956   return 0;
    957 }
    958 
    959 /* Create a pipe.  */
    960 
    961 static int
    962 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
    963 	       int binary ATTRIBUTE_UNUSED)
    964 {
    965   return pipe (p);
    966 }
    967 
    968 /* Get a FILE pointer to read from a file descriptor.  */
    969 
    970 static FILE *
    971 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
    972 		  int binary ATTRIBUTE_UNUSED)
    973 {
    974   return fdopen (fd, "r");
    975 }
    976 
    977 static FILE *
    978 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
    979 		  int binary ATTRIBUTE_UNUSED)
    980 {
    981   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
    982     return NULL;
    983   return fdopen (fd, "w");
    984 }
    985 
    986 static void
    987 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
    988 {
    989 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
    990   while (obj->sysdep != NULL)
    991     {
    992       struct status_list *this;
    993       struct status_list *next;
    994 
    995       this = (struct status_list *) obj->sysdep;
    996       next = this->next;
    997       free (this);
    998       obj->sysdep = (void *) next;
    999     }
   1000 #endif
   1001 }
   1002