(root)/
gcc-13.2.0/
libiberty/
pex-unix.c
       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-2023 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  
      62  #ifdef vfork /* Autoconf may define this to fork for us. */
      63  # define VFORK_STRING "fork"
      64  #else
      65  # define VFORK_STRING "vfork"
      66  #endif
      67  #ifdef HAVE_VFORK_H
      68  #include <vfork.h>
      69  #endif
      70  #if defined(VMS) && defined (__LONG_POINTERS)
      71  #ifndef __CHAR_PTR32
      72  typedef char * __char_ptr32
      73  __attribute__ ((mode (SI)));
      74  #endif
      75  
      76  typedef __char_ptr32 *__char_ptr_char_ptr32
      77  __attribute__ ((mode (SI)));
      78  
      79  /* Return a 32 bit pointer to an array of 32 bit pointers 
      80     given a 64 bit pointer to an array of 64 bit pointers.  */
      81  
      82  static __char_ptr_char_ptr32
      83  to_ptr32 (char **ptr64)
      84  {
      85    int argc;
      86    __char_ptr_char_ptr32 short_argv;
      87  
      88    /* Count number of arguments.  */
      89    for (argc = 0; ptr64[argc] != NULL; argc++)
      90      ;
      91  
      92    /* Reallocate argv with 32 bit pointers.  */
      93    short_argv = (__char_ptr_char_ptr32) decc$malloc
      94      (sizeof (__char_ptr32) * (argc + 1));
      95  
      96    for (argc = 0; ptr64[argc] != NULL; argc++)
      97      short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
      98  
      99    short_argv[argc] = (__char_ptr32) 0;
     100    return short_argv;
     101  
     102  }
     103  #else
     104  #define to_ptr32(argv) argv
     105  #endif
     106  
     107  /* File mode to use for private and world-readable files.  */
     108  
     109  #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
     110  #define PUBLIC_MODE  \
     111      (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
     112  #else
     113  #define PUBLIC_MODE 0666
     114  #endif
     115  
     116  /* Get the exit status of a particular process, and optionally get the
     117     time that it took.  This is simple if we have wait4, slightly
     118     harder if we have waitpid, and is a pain if we only have wait.  */
     119  
     120  static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
     121  
     122  #ifdef HAVE_WAIT4
     123  
     124  static pid_t
     125  pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
     126  	  struct pex_time *time)
     127  {
     128    pid_t ret;
     129    struct rusage r;
     130  
     131  #ifdef HAVE_WAITPID
     132    if (time == NULL)
     133      return waitpid (pid, status, 0);
     134  #endif
     135  
     136    ret = wait4 (pid, status, 0, &r);
     137  
     138    if (time != NULL)
     139      {
     140        time->user_seconds = r.ru_utime.tv_sec;
     141        time->user_microseconds= r.ru_utime.tv_usec;
     142        time->system_seconds = r.ru_stime.tv_sec;
     143        time->system_microseconds= r.ru_stime.tv_usec;
     144      }
     145  
     146    return ret;
     147  }
     148  
     149  #else /* ! defined (HAVE_WAIT4) */
     150  
     151  #ifdef HAVE_WAITPID
     152  
     153  #ifndef HAVE_GETRUSAGE
     154  
     155  static pid_t
     156  pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
     157  	  struct pex_time *time)
     158  {
     159    if (time != NULL)
     160      memset (time, 0, sizeof (struct pex_time));
     161    return waitpid (pid, status, 0);
     162  }
     163  
     164  #else /* defined (HAVE_GETRUSAGE) */
     165  
     166  static pid_t
     167  pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
     168  	  struct pex_time *time)
     169  {
     170    struct rusage r1, r2;
     171    pid_t ret;
     172  
     173    if (time == NULL)
     174      return waitpid (pid, status, 0);
     175  
     176    getrusage (RUSAGE_CHILDREN, &r1);
     177  
     178    ret = waitpid (pid, status, 0);
     179    if (ret < 0)
     180      return ret;
     181  
     182    getrusage (RUSAGE_CHILDREN, &r2);
     183  
     184    time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
     185    time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
     186    if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
     187      {
     188        --time->user_seconds;
     189        time->user_microseconds += 1000000;
     190      }
     191  
     192    time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
     193    time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
     194    if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
     195      {
     196        --time->system_seconds;
     197        time->system_microseconds += 1000000;
     198      }
     199  
     200    return ret;
     201  }
     202  
     203  #endif /* defined (HAVE_GETRUSAGE) */
     204  
     205  #else /* ! defined (HAVE_WAITPID) */
     206  
     207  struct status_list
     208  {
     209    struct status_list *next;
     210    pid_t pid;
     211    int status;
     212    struct pex_time time;
     213  };
     214  
     215  static pid_t
     216  pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
     217  {
     218    struct status_list **pp;
     219  
     220    for (pp = (struct status_list **) &obj->sysdep;
     221         *pp != NULL;
     222         pp = &(*pp)->next)
     223      {
     224        if ((*pp)->pid == pid)
     225  	{
     226  	  struct status_list *p;
     227  
     228  	  p = *pp;
     229  	  *status = p->status;
     230  	  if (time != NULL)
     231  	    *time = p->time;
     232  	  *pp = p->next;
     233  	  free (p);
     234  	  return pid;
     235  	}
     236      }
     237  
     238    while (1)
     239      {
     240        pid_t cpid;
     241        struct status_list *psl;
     242        struct pex_time pt;
     243  #ifdef HAVE_GETRUSAGE
     244        struct rusage r1, r2;
     245  #endif
     246  
     247        if (time != NULL)
     248  	{
     249  #ifdef HAVE_GETRUSAGE
     250  	  getrusage (RUSAGE_CHILDREN, &r1);
     251  #else
     252  	  memset (&pt, 0, sizeof (struct pex_time));
     253  #endif
     254  	}
     255  
     256        cpid = wait (status);
     257  
     258  #ifdef HAVE_GETRUSAGE
     259        if (time != NULL && cpid >= 0)
     260  	{
     261  	  getrusage (RUSAGE_CHILDREN, &r2);
     262  
     263  	  pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
     264  	  pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
     265  	  if (pt.user_microseconds < 0)
     266  	    {
     267  	      --pt.user_seconds;
     268  	      pt.user_microseconds += 1000000;
     269  	    }
     270  
     271  	  pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
     272  	  pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
     273  	  if (pt.system_microseconds < 0)
     274  	    {
     275  	      --pt.system_seconds;
     276  	      pt.system_microseconds += 1000000;
     277  	    }
     278  	}
     279  #endif
     280  
     281        if (cpid < 0 || cpid == pid)
     282  	{
     283  	  if (time != NULL)
     284  	    *time = pt;
     285  	  return cpid;
     286  	}
     287  
     288        psl = XNEW (struct status_list);
     289        psl->pid = cpid;
     290        psl->status = *status;
     291        if (time != NULL)
     292  	psl->time = pt;
     293        psl->next = (struct status_list *) obj->sysdep;
     294        obj->sysdep = (void *) psl;
     295      }
     296  }
     297  
     298  #endif /* ! defined (HAVE_WAITPID) */
     299  #endif /* ! defined (HAVE_WAIT4) */
     300  
     301  static int pex_unix_open_read (struct pex_obj *, const char *, int);
     302  static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
     303  static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
     304  				 char * const *, char * const *,
     305  				 int, int, int, int,
     306  				 const char **, int *);
     307  static int pex_unix_close (struct pex_obj *, int);
     308  static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
     309  			  int, const char **, int *);
     310  static int pex_unix_pipe (struct pex_obj *, int *, int);
     311  static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
     312  static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
     313  static void pex_unix_cleanup (struct pex_obj *);
     314  
     315  /* The list of functions we pass to the common routines.  */
     316  
     317  const struct pex_funcs funcs =
     318  {
     319    pex_unix_open_read,
     320    pex_unix_open_write,
     321    pex_unix_exec_child,
     322    pex_unix_close,
     323    pex_unix_wait,
     324    pex_unix_pipe,
     325    pex_unix_fdopenr,
     326    pex_unix_fdopenw,
     327    pex_unix_cleanup
     328  };
     329  
     330  /* Return a newly initialized pex_obj structure.  */
     331  
     332  struct pex_obj *
     333  pex_init (int flags, const char *pname, const char *tempbase)
     334  {
     335    return pex_init_common (flags, pname, tempbase, &funcs);
     336  }
     337  
     338  /* Open a file for reading.  */
     339  
     340  static int
     341  pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
     342  		    int binary ATTRIBUTE_UNUSED)
     343  {
     344    return open (name, O_RDONLY);
     345  }
     346  
     347  /* Open a file for writing.  */
     348  
     349  static int
     350  pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
     351  		     int binary ATTRIBUTE_UNUSED, int append)
     352  {
     353    /* Note that we can't use O_EXCL here because gcc may have already
     354       created the temporary file via make_temp_file.  */
     355    return open (name, O_WRONLY | O_CREAT
     356  		     | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE);
     357  }
     358  
     359  /* Close a file.  */
     360  
     361  static int
     362  pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
     363  {
     364    return close (fd);
     365  }
     366  
     367  /* Execute a child.  */
     368  
     369  #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
     370  /* Implementation of pex->exec_child using the Cygwin spawn operation.  */
     371  
     372  /* Subroutine of pex_unix_exec_child.  Move OLD_FD to a new file descriptor
     373     to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the
     374     saved copy to be close-on-exec.  Move CHILD_FD into OLD_FD.  If CHILD_FD
     375     is -1, OLD_FD is to be closed.  Return -1 on error.  */
     376  
     377  static int
     378  save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd)
     379  {
     380    int new_fd, flags;
     381  
     382    flags = fcntl (old_fd, F_GETFD);
     383  
     384    /* If we could not retrieve the flags, then OLD_FD was not open.  */
     385    if (flags < 0)
     386      {
     387        new_fd = -1, flags = 0;
     388        if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0)
     389  	return -1;
     390      }
     391    /* If we wish to close OLD_FD, just mark it CLOEXEC.  */
     392    else if (child_fd == -1)
     393      {
     394        new_fd = old_fd;
     395        if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0)
     396  	return -1;
     397      }
     398    /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD.  */
     399    else
     400      {
     401  #ifdef F_DUPFD_CLOEXEC
     402        new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3);
     403        if (new_fd < 0)
     404  	return -1;
     405  #else
     406        /* Prefer F_DUPFD over dup in order to avoid getting a new fd
     407  	 in the range 0-2, right where a new stderr fd might get put.  */
     408        new_fd = fcntl (old_fd, F_DUPFD, 3);
     409        if (new_fd < 0)
     410  	return -1;
     411        if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0)
     412  	return -1;
     413  #endif
     414        if (dup2 (child_fd, old_fd) < 0)
     415  	return -1;
     416      }
     417  
     418    *pflags = flags;
     419    if (pnew_fd)
     420      *pnew_fd = new_fd;
     421    else if (new_fd != old_fd)
     422      abort ();
     423  
     424    return 0;
     425  }
     426  
     427  /* Subroutine of pex_unix_exec_child.  Move SAVE_FD back to OLD_FD
     428     restoring FLAGS.  If SAVE_FD < 0, OLD_FD is to be closed.  */
     429  
     430  static int
     431  restore_fd(int old_fd, int save_fd, int flags)
     432  {
     433    /* For SAVE_FD < 0, all we have to do is restore the
     434       "closed-ness" of the original.  */
     435    if (save_fd < 0)
     436      return close (old_fd);
     437  
     438    /* For SAVE_FD == OLD_FD, all we have to do is restore the
     439       original setting of the CLOEXEC flag.  */
     440    if (save_fd == old_fd)
     441      {
     442        if (flags & FD_CLOEXEC)
     443  	return 0;
     444        return fcntl (old_fd, F_SETFD, flags);
     445      }
     446  
     447    /* Otherwise we have to move the descriptor back, restore the flags,
     448       and close the saved copy.  */
     449  #ifdef HAVE_DUP3
     450    if (flags == FD_CLOEXEC)
     451      {
     452        if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0)
     453  	return -1;
     454      }
     455    else
     456  #endif
     457      {
     458        if (dup2 (save_fd, old_fd) < 0)
     459  	return -1;
     460        if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0)
     461  	return -1;
     462      }
     463    return close (save_fd);
     464  }
     465  
     466  static pid_t
     467  pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED,
     468  		     int flags, const char *executable,
     469  		     char * const * argv, char * const * env,
     470                       int in, int out, int errdes, int toclose,
     471  		     const char **errmsg, int *err)
     472  {
     473    int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0;
     474    int save_in = -1, save_out = -1, save_err = -1;
     475    int max, retries;
     476    pid_t pid;
     477  
     478    if (flags & PEX_STDERR_TO_STDOUT)
     479      errdes = out;
     480  
     481    /* We need the three standard file descriptors to be set up as for
     482       the child before we perform the spawn.  The file descriptors for
     483       the parent need to be moved and marked for close-on-exec.  */
     484    if (in != STDIN_FILE_NO
     485        && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0)
     486      goto error_dup2;
     487    if (out != STDOUT_FILE_NO
     488        && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0)
     489      goto error_dup2;
     490    if (errdes != STDERR_FILE_NO
     491        && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0)
     492      goto error_dup2;
     493    if (toclose >= 0
     494        && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0)
     495      goto error_dup2;
     496  
     497    /* Now that we've moved the file descriptors for the child into place,
     498       close the originals.  Be careful not to close any of the standard
     499       file descriptors that we just set up.  */
     500    max = -1;
     501    if (errdes >= 0)
     502      max = STDERR_FILE_NO;
     503    else if (out >= 0)
     504      max = STDOUT_FILE_NO;
     505    else if (in >= 0)
     506      max = STDIN_FILE_NO;
     507    if (in > max)
     508      close (in);
     509    if (out > max)
     510      close (out);
     511    if (errdes > max && errdes != out)
     512      close (errdes);
     513  
     514    /* If we were not given an environment, use the global environment.  */
     515    if (env == NULL)
     516      env = environ;
     517  
     518    /* Launch the program.  If we get EAGAIN (normally out of pid's), try
     519       again a few times with increasing backoff times.  */
     520    retries = 0;
     521    while (1)
     522      {
     523        typedef const char * const *cc_cp;
     524  
     525        if (flags & PEX_SEARCH)
     526  	pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
     527        else
     528  	pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
     529  
     530        if (pid > 0)
     531  	break;
     532  
     533        *err = errno;
     534        *errmsg = "spawn";
     535        if (errno != EAGAIN || ++retries == 4)
     536  	return (pid_t) -1;
     537        sleep (1 << retries);
     538      }
     539  
     540    /* Success.  Restore the parent's file descriptors that we saved above.  */
     541    if (toclose >= 0
     542        && restore_fd (toclose, toclose, fl_tc) < 0)
     543      goto error_dup2;
     544    if (in != STDIN_FILE_NO
     545        && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0)
     546      goto error_dup2;
     547    if (out != STDOUT_FILE_NO
     548        && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0)
     549      goto error_dup2;
     550    if (errdes != STDERR_FILE_NO
     551        && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0)
     552      goto error_dup2;
     553  
     554    return pid;
     555  
     556   error_dup2:
     557    *err = errno;
     558    *errmsg = "dup2";
     559    return (pid_t) -1;
     560  }
     561  
     562  #else
     563  /* Implementation of pex->exec_child using standard vfork + exec.  */
     564  
     565  static pid_t
     566  pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
     567  		     char * const * argv, char * const * env,
     568                       int in, int out, int errdes,
     569  		     int toclose, const char **errmsg, int *err)
     570  {
     571    pid_t pid = -1;
     572    /* Tuple to communicate error from child to parent.  We can safely
     573       transfer string literal pointers as both run with identical
     574       address mappings.  */
     575    struct fn_err 
     576    {
     577      const char *fn;
     578      int err;
     579    };
     580    volatile int do_pipe = 0;
     581    volatile int pipes[2]; /* [0]:reader,[1]:writer.  */
     582  #ifdef O_CLOEXEC
     583    do_pipe = 1;
     584  #endif
     585    if (do_pipe)
     586      {
     587  #ifdef HAVE_PIPE2
     588        if (pipe2 ((int *)pipes, O_CLOEXEC))
     589  	do_pipe = 0;
     590  #else
     591        if (pipe ((int *)pipes))
     592  	do_pipe = 0;
     593        else
     594  	{
     595  	  if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1)
     596  	    {
     597  	      close (pipes[0]);
     598  	      close (pipes[1]);
     599  	      do_pipe = 0;
     600  	    }
     601  	}
     602  #endif
     603      }
     604  
     605    /* We declare these to be volatile to avoid warnings from gcc about
     606       them being clobbered by vfork.  */
     607    volatile int sleep_interval = 1;
     608    volatile int retries;
     609  
     610    /* We vfork and then set environ in the child before calling execvp.
     611       This clobbers the parent's environ so we need to restore it.
     612       It would be nice to use one of the exec* functions that takes an
     613       environment as a parameter, but that may have portability
     614       issues.  It is marked volatile so the child doesn't consider it a
     615       dead variable and therefore clobber where ever it is stored.  */
     616    char **volatile save_environ = environ;
     617  
     618    for (retries = 0; retries < 4; ++retries)
     619      {
     620        pid = vfork ();
     621        if (pid >= 0)
     622  	break;
     623        sleep (sleep_interval);
     624        sleep_interval *= 2;
     625      }
     626  
     627    switch (pid)
     628      {
     629      case -1:
     630        if (do_pipe)
     631  	{
     632  	  close (pipes[0]);
     633  	  close (pipes[1]);
     634  	}
     635        *err = errno;
     636        *errmsg = VFORK_STRING;
     637        return (pid_t) -1;
     638  
     639      case 0:
     640        /* Child process.  */
     641        {
     642  	struct fn_err failed;
     643  	failed.fn = NULL;
     644  
     645  	if (do_pipe)
     646  	  close (pipes[0]);
     647  	if (!failed.fn && in != STDIN_FILE_NO)
     648  	  {
     649  	    if (dup2 (in, STDIN_FILE_NO) < 0)
     650  	      failed.fn = "dup2", failed.err = errno;
     651  	    else if (close (in) < 0)
     652  	      failed.fn = "close", failed.err = errno;
     653  	  }
     654  	if (!failed.fn && out != STDOUT_FILE_NO)
     655  	  {
     656  	    if (dup2 (out, STDOUT_FILE_NO) < 0)
     657  	      failed.fn = "dup2", failed.err = errno;
     658  	    else if (close (out) < 0)
     659  	      failed.fn = "close", failed.err = errno;
     660  	  }
     661  	if (!failed.fn && errdes != STDERR_FILE_NO)
     662  	  {
     663  	    if (dup2 (errdes, STDERR_FILE_NO) < 0)
     664  	      failed.fn = "dup2", failed.err = errno;
     665  	    else if (close (errdes) < 0)
     666  	      failed.fn = "close", failed.err = errno;
     667  	  }
     668  	if (!failed.fn && toclose >= 0)
     669  	  {
     670  	    if (close (toclose) < 0)
     671  	      failed.fn = "close", failed.err = errno;
     672  	  }
     673  	if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
     674  	  {
     675  	    if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
     676  	      failed.fn = "dup2", failed.err = errno;
     677  	  }
     678  	if (!failed.fn)
     679  	  {
     680  	    if (env)
     681  	      /* NOTE: In a standard vfork implementation this clobbers
     682  		 the parent's copy of environ "too" (in reality there's
     683  		 only one copy).  This is ok as we restore it below.  */
     684  	      environ = (char**) env;
     685  	    if ((flags & PEX_SEARCH) != 0)
     686  	      {
     687  		execvp (executable, to_ptr32 (argv));
     688  		failed.fn = "execvp", failed.err = errno;
     689  	      }
     690  	    else
     691  	      {
     692  		execv (executable, to_ptr32 (argv));
     693  		failed.fn = "execv", failed.err = errno;
     694  	      }
     695  	  }
     696  
     697  	/* Something failed, report an error.  We don't use stdio
     698  	   routines, because we might be here due to a vfork call.  */
     699  	ssize_t retval = 0;
     700  
     701  	if (!do_pipe
     702  	    || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed))
     703  	  {
     704  	    /* The parent will not see our scream above, so write to
     705  	       stdout.  */
     706  #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
     707  	    writeerr (obj->pname);
     708  	    writeerr (": error trying to exec '");
     709  	    writeerr (executable);
     710  	    writeerr ("': ");
     711  	    writeerr (failed.fn);
     712  	    writeerr (": ");
     713  	    writeerr (xstrerror (failed.err));
     714  	    writeerr ("\n");
     715  #undef writeerr
     716  	  }
     717  
     718  	/* Exit with -2 if the error output failed, too.  */
     719  	_exit (retval < 0 ? -2 : -1);
     720        }
     721        /* NOTREACHED */
     722        return (pid_t) -1;
     723  
     724      default:
     725        /* Parent process.  */
     726        {
     727  	/* Restore environ.  Note that the parent either doesn't run
     728  	   until the child execs/exits (standard vfork behaviour), or
     729  	   if it does run then vfork is behaving more like fork.  In
     730  	   either case we needn't worry about clobbering the child's
     731  	   copy of environ.  */
     732  	environ = save_environ;
     733  
     734  	struct fn_err failed;
     735  	failed.fn = NULL;
     736  	if (do_pipe)
     737  	  {
     738  	    close (pipes[1]);
     739  	    ssize_t len = read (pipes[0], &failed, sizeof (failed));
     740  	    if (len < 0)
     741  	      failed.fn = NULL;
     742  	    close (pipes[0]);
     743  	  }
     744  
     745  	if (!failed.fn && in != STDIN_FILE_NO)
     746  	  if (close (in) < 0)
     747  	    failed.fn = "close", failed.err = errno;
     748  	if (!failed.fn && out != STDOUT_FILE_NO)
     749  	  if (close (out) < 0)
     750  	    failed.fn = "close", failed.err = errno;
     751  	if (!failed.fn && errdes != STDERR_FILE_NO)
     752  	  if (close (errdes) < 0)
     753  	    failed.fn = "close", failed.err = errno;
     754  
     755  	if (failed.fn)
     756  	  {
     757  	    *err = failed.err;
     758  	    *errmsg = failed.fn;
     759  	    return (pid_t) -1;
     760  	  }
     761        }
     762        return pid;
     763      }
     764  }
     765  #endif /* SPAWN */
     766  
     767  /* Wait for a child process to complete.  */
     768  
     769  static int
     770  pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
     771  	       struct pex_time *time, int done, const char **errmsg,
     772  	       int *err)
     773  {
     774    /* If we are cleaning up when the caller didn't retrieve process
     775       status for some reason, encourage the process to go away.  */
     776    if (done)
     777      kill (pid, SIGTERM);
     778  
     779    if (pex_wait (obj, pid, status, time) < 0)
     780      {
     781        *err = errno;
     782        *errmsg = "wait";
     783        return -1;
     784      }
     785  
     786    return 0;
     787  }
     788  
     789  /* Create a pipe.  */
     790  
     791  static int
     792  pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
     793  	       int binary ATTRIBUTE_UNUSED)
     794  {
     795    return pipe (p);
     796  }
     797  
     798  /* Get a FILE pointer to read from a file descriptor.  */
     799  
     800  static FILE *
     801  pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
     802  		  int binary ATTRIBUTE_UNUSED)
     803  {
     804    return fdopen (fd, "r");
     805  }
     806  
     807  static FILE *
     808  pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
     809  		  int binary ATTRIBUTE_UNUSED)
     810  {
     811    if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
     812      return NULL;
     813    return fdopen (fd, "w");
     814  }
     815  
     816  static void
     817  pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
     818  {
     819  #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
     820    while (obj->sysdep != NULL)
     821      {
     822        struct status_list *this;
     823        struct status_list *next;
     824  
     825        this = (struct status_list *) obj->sysdep;
     826        next = this->next;
     827        free (this);
     828        obj->sysdep = (void *) next;
     829      }
     830  #endif
     831  }