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