Home | History | Annotate | Line # | Download | only in libiberty
pex-unix.c revision 1.1.1.1
      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, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009
      5    Free Software Foundation, Inc.
      6 
      7 This file is part of the libiberty library.
      8 Libiberty is free software; you can redistribute it and/or
      9 modify it under the terms of the GNU Library General Public
     10 License as published by the Free Software Foundation; either
     11 version 2 of the License, or (at your option) any later version.
     12 
     13 Libiberty is distributed in the hope that it will be useful,
     14 but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16 Library General Public License for more details.
     17 
     18 You should have received a copy of the GNU Library General Public
     19 License along with libiberty; see the file COPYING.LIB.  If not,
     20 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     21 Boston, MA 02110-1301, USA.  */
     22 
     23 #include "config.h"
     24 #include "libiberty.h"
     25 #include "pex-common.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 
     59 
     60 #ifdef vfork /* Autoconf may define this to fork for us. */
     61 # define VFORK_STRING "fork"
     62 #else
     63 # define VFORK_STRING "vfork"
     64 #endif
     65 #ifdef HAVE_VFORK_H
     66 #include <vfork.h>
     67 #endif
     68 #if defined(VMS) && defined (__LONG_POINTERS)
     69 #ifndef __CHAR_PTR32
     70 typedef char * __char_ptr32
     71 __attribute__ ((mode (SI)));
     72 #endif
     73 
     74 typedef __char_ptr32 *__char_ptr_char_ptr32
     75 __attribute__ ((mode (SI)));
     76 
     77 /* Return a 32 bit pointer to an array of 32 bit pointers
     78    given a 64 bit pointer to an array of 64 bit pointers.  */
     79 
     80 static __char_ptr_char_ptr32
     81 to_ptr32 (char **ptr64)
     82 {
     83   int argc;
     84   __char_ptr_char_ptr32 short_argv;
     85 
     86   for (argc=0; ptr64[argc]; argc++);
     87 
     88   /* Reallocate argv with 32 bit pointers.  */
     89   short_argv = (__char_ptr_char_ptr32) decc$malloc
     90     (sizeof (__char_ptr32) * (argc + 1));
     91 
     92   for (argc=0; ptr64[argc]; argc++)
     93     short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
     94 
     95   short_argv[argc] = (__char_ptr32) 0;
     96   return short_argv;
     97 
     98 }
     99 #else
    100 #define to_ptr32(argv) argv
    101 #endif
    102 
    103 /* File mode to use for private and world-readable files.  */
    104 
    105 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
    106 #define PUBLIC_MODE  \
    107     (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
    108 #else
    109 #define PUBLIC_MODE 0666
    110 #endif
    111 
    112 /* Get the exit status of a particular process, and optionally get the
    113    time that it took.  This is simple if we have wait4, slightly
    114    harder if we have waitpid, and is a pain if we only have wait.  */
    115 
    116 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
    117 
    118 #ifdef HAVE_WAIT4
    119 
    120 static pid_t
    121 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    122 	  struct pex_time *time)
    123 {
    124   pid_t ret;
    125   struct rusage r;
    126 
    127 #ifdef HAVE_WAITPID
    128   if (time == NULL)
    129     return waitpid (pid, status, 0);
    130 #endif
    131 
    132   ret = wait4 (pid, status, 0, &r);
    133 
    134   if (time != NULL)
    135     {
    136       time->user_seconds = r.ru_utime.tv_sec;
    137       time->user_microseconds= r.ru_utime.tv_usec;
    138       time->system_seconds = r.ru_stime.tv_sec;
    139       time->system_microseconds= r.ru_stime.tv_usec;
    140     }
    141 
    142   return ret;
    143 }
    144 
    145 #else /* ! defined (HAVE_WAIT4) */
    146 
    147 #ifdef HAVE_WAITPID
    148 
    149 #ifndef HAVE_GETRUSAGE
    150 
    151 static pid_t
    152 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    153 	  struct pex_time *time)
    154 {
    155   if (time != NULL)
    156     memset (time, 0, sizeof (struct pex_time));
    157   return waitpid (pid, status, 0);
    158 }
    159 
    160 #else /* defined (HAVE_GETRUSAGE) */
    161 
    162 static pid_t
    163 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
    164 	  struct pex_time *time)
    165 {
    166   struct rusage r1, r2;
    167   pid_t ret;
    168 
    169   if (time == NULL)
    170     return waitpid (pid, status, 0);
    171 
    172   getrusage (RUSAGE_CHILDREN, &r1);
    173 
    174   ret = waitpid (pid, status, 0);
    175   if (ret < 0)
    176     return ret;
    177 
    178   getrusage (RUSAGE_CHILDREN, &r2);
    179 
    180   time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
    181   time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
    182   if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
    183     {
    184       --time->user_seconds;
    185       time->user_microseconds += 1000000;
    186     }
    187 
    188   time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
    189   time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
    190   if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
    191     {
    192       --time->system_seconds;
    193       time->system_microseconds += 1000000;
    194     }
    195 
    196   return ret;
    197 }
    198 
    199 #endif /* defined (HAVE_GETRUSAGE) */
    200 
    201 #else /* ! defined (HAVE_WAITPID) */
    202 
    203 struct status_list
    204 {
    205   struct status_list *next;
    206   pid_t pid;
    207   int status;
    208   struct pex_time time;
    209 };
    210 
    211 static pid_t
    212 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
    213 {
    214   struct status_list **pp;
    215 
    216   for (pp = (struct status_list **) &obj->sysdep;
    217        *pp != NULL;
    218        pp = &(*pp)->next)
    219     {
    220       if ((*pp)->pid == pid)
    221 	{
    222 	  struct status_list *p;
    223 
    224 	  p = *pp;
    225 	  *status = p->status;
    226 	  if (time != NULL)
    227 	    *time = p->time;
    228 	  *pp = p->next;
    229 	  free (p);
    230 	  return pid;
    231 	}
    232     }
    233 
    234   while (1)
    235     {
    236       pid_t cpid;
    237       struct status_list *psl;
    238       struct pex_time pt;
    239 #ifdef HAVE_GETRUSAGE
    240       struct rusage r1, r2;
    241 #endif
    242 
    243       if (time != NULL)
    244 	{
    245 #ifdef HAVE_GETRUSAGE
    246 	  getrusage (RUSAGE_CHILDREN, &r1);
    247 #else
    248 	  memset (&pt, 0, sizeof (struct pex_time));
    249 #endif
    250 	}
    251 
    252       cpid = wait (status);
    253 
    254 #ifdef HAVE_GETRUSAGE
    255       if (time != NULL && cpid >= 0)
    256 	{
    257 	  getrusage (RUSAGE_CHILDREN, &r2);
    258 
    259 	  pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
    260 	  pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
    261 	  if (pt.user_microseconds < 0)
    262 	    {
    263 	      --pt.user_seconds;
    264 	      pt.user_microseconds += 1000000;
    265 	    }
    266 
    267 	  pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
    268 	  pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
    269 	  if (pt.system_microseconds < 0)
    270 	    {
    271 	      --pt.system_seconds;
    272 	      pt.system_microseconds += 1000000;
    273 	    }
    274 	}
    275 #endif
    276 
    277       if (cpid < 0 || cpid == pid)
    278 	{
    279 	  if (time != NULL)
    280 	    *time = pt;
    281 	  return cpid;
    282 	}
    283 
    284       psl = XNEW (struct status_list);
    285       psl->pid = cpid;
    286       psl->status = *status;
    287       if (time != NULL)
    288 	psl->time = pt;
    289       psl->next = (struct status_list *) obj->sysdep;
    290       obj->sysdep = (void *) psl;
    291     }
    292 }
    293 
    294 #endif /* ! defined (HAVE_WAITPID) */
    295 #endif /* ! defined (HAVE_WAIT4) */
    296 
    297 static void pex_child_error (struct pex_obj *, const char *, const char *, int)
    298      ATTRIBUTE_NORETURN;
    299 static int pex_unix_open_read (struct pex_obj *, const char *, int);
    300 static int pex_unix_open_write (struct pex_obj *, const char *, int);
    301 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
    302 				 char * const *, char * const *,
    303 				 int, int, int, int,
    304 				 const char **, int *);
    305 static int pex_unix_close (struct pex_obj *, int);
    306 static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
    307 			  int, const char **, int *);
    308 static int pex_unix_pipe (struct pex_obj *, int *, int);
    309 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
    310 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
    311 static void pex_unix_cleanup (struct pex_obj *);
    312 
    313 /* The list of functions we pass to the common routines.  */
    314 
    315 const struct pex_funcs funcs =
    316 {
    317   pex_unix_open_read,
    318   pex_unix_open_write,
    319   pex_unix_exec_child,
    320   pex_unix_close,
    321   pex_unix_wait,
    322   pex_unix_pipe,
    323   pex_unix_fdopenr,
    324   pex_unix_fdopenw,
    325   pex_unix_cleanup
    326 };
    327 
    328 /* Return a newly initialized pex_obj structure.  */
    329 
    330 struct pex_obj *
    331 pex_init (int flags, const char *pname, const char *tempbase)
    332 {
    333   return pex_init_common (flags, pname, tempbase, &funcs);
    334 }
    335 
    336 /* Open a file for reading.  */
    337 
    338 static int
    339 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
    340 		    int binary ATTRIBUTE_UNUSED)
    341 {
    342   return open (name, O_RDONLY);
    343 }
    344 
    345 /* Open a file for writing.  */
    346 
    347 static int
    348 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
    349 		     int binary ATTRIBUTE_UNUSED)
    350 {
    351   /* Note that we can't use O_EXCL here because gcc may have already
    352      created the temporary file via make_temp_file.  */
    353   return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE);
    354 }
    355 
    356 /* Close a file.  */
    357 
    358 static int
    359 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
    360 {
    361   return close (fd);
    362 }
    363 
    364 /* Report an error from a child process.  We don't use stdio routines,
    365    because we might be here due to a vfork call.  */
    366 
    367 static void
    368 pex_child_error (struct pex_obj *obj, const char *executable,
    369 		 const char *errmsg, int err)
    370 {
    371   int retval = 0;
    372 #define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
    373   writeerr (obj->pname);
    374   writeerr (": error trying to exec '");
    375   writeerr (executable);
    376   writeerr ("': ");
    377   writeerr (errmsg);
    378   writeerr (": ");
    379   writeerr (xstrerror (err));
    380   writeerr ("\n");
    381 #undef writeerr
    382   /* Exit with -2 if the error output failed, too.  */
    383   _exit (retval == 0 ? -1 : -2);
    384 }
    385 
    386 /* Execute a child.  */
    387 
    388 extern char **environ;
    389 
    390 static pid_t
    391 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
    392 		     char * const * argv, char * const * env,
    393                      int in, int out, int errdes,
    394 		     int toclose, const char **errmsg, int *err)
    395 {
    396   pid_t pid;
    397 
    398   /* We declare these to be volatile to avoid warnings from gcc about
    399      them being clobbered by vfork.  */
    400   volatile int sleep_interval;
    401   volatile int retries;
    402 
    403   /* We vfork and then set environ in the child before calling execvp.
    404      This clobbers the parent's environ so we need to restore it.
    405      It would be nice to use one of the exec* functions that takes an
    406      environment as a parameter, but that may have portability issues.  */
    407   char **save_environ = environ;
    408 
    409   sleep_interval = 1;
    410   pid = -1;
    411   for (retries = 0; retries < 4; ++retries)
    412     {
    413       pid = vfork ();
    414       if (pid >= 0)
    415 	break;
    416       sleep (sleep_interval);
    417       sleep_interval *= 2;
    418     }
    419 
    420   switch (pid)
    421     {
    422     case -1:
    423       *err = errno;
    424       *errmsg = VFORK_STRING;
    425       return (pid_t) -1;
    426 
    427     case 0:
    428       /* Child process.  */
    429       if (in != STDIN_FILE_NO)
    430 	{
    431 	  if (dup2 (in, STDIN_FILE_NO) < 0)
    432 	    pex_child_error (obj, executable, "dup2", errno);
    433 	  if (close (in) < 0)
    434 	    pex_child_error (obj, executable, "close", errno);
    435 	}
    436       if (out != STDOUT_FILE_NO)
    437 	{
    438 	  if (dup2 (out, STDOUT_FILE_NO) < 0)
    439 	    pex_child_error (obj, executable, "dup2", errno);
    440 	  if (close (out) < 0)
    441 	    pex_child_error (obj, executable, "close", errno);
    442 	}
    443       if (errdes != STDERR_FILE_NO)
    444 	{
    445 	  if (dup2 (errdes, STDERR_FILE_NO) < 0)
    446 	    pex_child_error (obj, executable, "dup2", errno);
    447 	  if (close (errdes) < 0)
    448 	    pex_child_error (obj, executable, "close", errno);
    449 	}
    450       if (toclose >= 0)
    451 	{
    452 	  if (close (toclose) < 0)
    453 	    pex_child_error (obj, executable, "close", errno);
    454 	}
    455       if ((flags & PEX_STDERR_TO_STDOUT) != 0)
    456 	{
    457 	  if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
    458 	    pex_child_error (obj, executable, "dup2", errno);
    459 	}
    460 
    461       if (env)
    462 	{
    463 	  /* NOTE: In a standard vfork implementation this clobbers the
    464 	     parent's copy of environ "too" (in reality there's only one copy).
    465 	     This is ok as we restore it below.  */
    466 	  environ = (char**) env;
    467 	}
    468 
    469       if ((flags & PEX_SEARCH) != 0)
    470 	{
    471 	  execvp (executable, to_ptr32 (argv));
    472 	  pex_child_error (obj, executable, "execvp", errno);
    473 	}
    474       else
    475 	{
    476 	  execv (executable, to_ptr32 (argv));
    477 	  pex_child_error (obj, executable, "execv", errno);
    478 	}
    479 
    480       /* NOTREACHED */
    481       return (pid_t) -1;
    482 
    483     default:
    484       /* Parent process.  */
    485 
    486       /* Restore environ.
    487 	 Note that the parent either doesn't run until the child execs/exits
    488 	 (standard vfork behaviour), or if it does run then vfork is behaving
    489 	 more like fork.  In either case we needn't worry about clobbering
    490 	 the child's copy of environ.  */
    491       environ = save_environ;
    492 
    493       if (in != STDIN_FILE_NO)
    494 	{
    495 	  if (close (in) < 0)
    496 	    {
    497 	      *err = errno;
    498 	      *errmsg = "close";
    499 	      return (pid_t) -1;
    500 	    }
    501 	}
    502       if (out != STDOUT_FILE_NO)
    503 	{
    504 	  if (close (out) < 0)
    505 	    {
    506 	      *err = errno;
    507 	      *errmsg = "close";
    508 	      return (pid_t) -1;
    509 	    }
    510 	}
    511       if (errdes != STDERR_FILE_NO)
    512 	{
    513 	  if (close (errdes) < 0)
    514 	    {
    515 	      *err = errno;
    516 	      *errmsg = "close";
    517 	      return (pid_t) -1;
    518 	    }
    519 	}
    520 
    521       return pid;
    522     }
    523 }
    524 
    525 /* Wait for a child process to complete.  */
    526 
    527 static int
    528 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
    529 	       struct pex_time *time, int done, const char **errmsg,
    530 	       int *err)
    531 {
    532   /* If we are cleaning up when the caller didn't retrieve process
    533      status for some reason, encourage the process to go away.  */
    534   if (done)
    535     kill (pid, SIGTERM);
    536 
    537   if (pex_wait (obj, pid, status, time) < 0)
    538     {
    539       *err = errno;
    540       *errmsg = "wait";
    541       return -1;
    542     }
    543 
    544   return 0;
    545 }
    546 
    547 /* Create a pipe.  */
    548 
    549 static int
    550 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
    551 	       int binary ATTRIBUTE_UNUSED)
    552 {
    553   return pipe (p);
    554 }
    555 
    556 /* Get a FILE pointer to read from a file descriptor.  */
    557 
    558 static FILE *
    559 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
    560 		  int binary ATTRIBUTE_UNUSED)
    561 {
    562   return fdopen (fd, "r");
    563 }
    564 
    565 static FILE *
    566 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
    567 		  int binary ATTRIBUTE_UNUSED)
    568 {
    569   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
    570     return NULL;
    571   return fdopen (fd, "w");
    572 }
    573 
    574 static void
    575 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
    576 {
    577 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
    578   while (obj->sysdep != NULL)
    579     {
    580       struct status_list *this;
    581       struct status_list *next;
    582 
    583       this = (struct status_list *) obj->sysdep;
    584       next = this->next;
    585       free (this);
    586       obj->sysdep = (void *) next;
    587     }
    588 #endif
    589 }
    590