(linenum→info "unix/slp.c:2238")

binutils/2.18/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, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
    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: #ifdef VMS
   69: #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
   70:                lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
   71: #endif /* VMS */
   72: 
   73: 
   74: /* File mode to use for private and world-readable files.  */
   75: 
   76: #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
   77: #define PUBLIC_MODE  \
   78:     (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
   79: #else
   80: #define PUBLIC_MODE 0666
   81: #endif
   82: 
   83: /* Get the exit status of a particular process, and optionally get the
   84:    time that it took.  This is simple if we have wait4, slightly
   85:    harder if we have waitpid, and is a pain if we only have wait.  */
   86: 
   87: static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
   88: 
   89: #ifdef HAVE_WAIT4
   90: 
   91: static pid_t
   92: pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
   93:           struct pex_time *time)
   94: {
   95:   pid_t ret;
   96:   struct rusage r;
   97: 
   98: #ifdef HAVE_WAITPID
   99:   if (time == NULL)
  100:     return waitpid (pid, status, 0);
  101: #endif
  102: 
  103:   ret = wait4 (pid, status, 0, &r);
  104: 
  105:   if (time != NULL)
  106:     {
  107:       time->user_seconds = r.ru_utime.tv_sec;
  108:       time->user_microseconds= r.ru_utime.tv_usec;
  109:       time->system_seconds = r.ru_stime.tv_sec;
  110:       time->system_microseconds= r.ru_stime.tv_usec;
  111:     }
  112: 
  113:   return ret;
  114: }
  115: 
  116: #else /* ! defined (HAVE_WAIT4) */
  117: 
  118: #ifdef HAVE_WAITPID
  119: 
  120: #ifndef HAVE_GETRUSAGE
  121: 
  122: static pid_t
  123: pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
  124:           struct pex_time *time)
  125: {
  126:   if (time != NULL)
  127:     memset (time, 0, sizeof (struct pex_time));
  128:   return waitpid (pid, status, 0);
  129: }
  130: 
  131: #else /* defined (HAVE_GETRUSAGE) */
  132: 
  133: static pid_t
  134: pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
  135:           struct pex_time *time)
  136: {
  137:   struct rusage r1, r2;
  138:   pid_t ret;
  139: 
  140:   if (time == NULL)
  141:     return waitpid (pid, status, 0);
  142: 
  143:   getrusage (RUSAGE_CHILDREN, &r1);
  144: 
  145:   ret = waitpid (pid, status, 0);
  146:   if (ret < 0)
  147:     return ret;
  148: 
  149:   getrusage (RUSAGE_CHILDREN, &r2);
  150: 
  151:   time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
  152:   time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
  153:   if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
  154:     {
  155:       --time->user_seconds;
  156:       time->user_microseconds += 1000000;
  157:     }
  158: 
  159:   time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
  160:   time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
  161:   if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
  162:     {
  163:       --time->system_seconds;
  164:       time->system_microseconds += 1000000;
  165:     }
  166: 
  167:   return ret;
  168: }
  169: 
  170: #endif /* defined (HAVE_GETRUSAGE) */
  171: 
  172: #else /* ! defined (HAVE_WAITPID) */
  173: 
  174: struct status_list
  175: {
  176:   struct status_list *next;
  177:   pid_t pid;
  178:   int status;
  179:   struct pex_time time;
  180: };
  181: 
  182: static pid_t
  183: pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
  184: {
  185:   struct status_list **pp;
  186: 
  187:   for (pp = (struct status_list **) &obj->sysdep;
  188:        *pp != NULL;
  189:        pp = &(*pp)->next)
  190:     {
  191:       if ((*pp)->pid == pid)
  192:         {
  193:           struct status_list *p;
  194: 
  195:           p = *pp;
  196:           *status = p->status;
  197:           if (time != NULL)
  198:             *time = p->time;
  199:           *pp = p->next;
  200:           free (p);
  201:           return pid;
  202:         }
  203:     }
  204: 
  205:   while (1)
  206:     {
  207:       pid_t cpid;
  208:       struct status_list *psl;
  209:       struct pex_time pt;
  210: #ifdef HAVE_GETRUSAGE
  211:       struct rusage r1, r2;
  212: #endif
  213: 
  214:       if (time != NULL)
  215:         {
  216: #ifdef HAVE_GETRUSAGE
  217:           getrusage (RUSAGE_CHILDREN, &r1);
  218: #else
  219:           memset (&pt, 0, sizeof (struct pex_time));
  220: #endif
  221:         }
  222: 
  223:       cpid = wait (status);
  224: 
  225: #ifdef HAVE_GETRUSAGE
  226:       if (time != NULL && cpid >= 0)
  227:         {
  228:           getrusage (RUSAGE_CHILDREN, &r2);
  229: 
  230:           pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
  231:           pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
  232:           if (pt.user_microseconds < 0)
  233:             {
  234:               --pt.user_seconds;
  235:               pt.user_microseconds += 1000000;
  236:             }
  237: 
  238:           pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
  239:           pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
  240:           if (pt.system_microseconds < 0)
  241:             {
  242:               --pt.system_seconds;
  243:               pt.system_microseconds += 1000000;
  244:             }
  245:         }
  246: #endif
  247: 
  248:       if (cpid < 0 || cpid == pid)
  249:         {
  250:           if (time != NULL)
  251:             *time = pt;
  252:           return cpid;
  253:         }
  254: 
  255:       psl = XNEW (struct status_list);
  256:       psl->pid = cpid;
  257:       psl->status = *status;
  258:       if (time != NULL)
  259:         psl->time = pt;
  260:       psl->next = (struct status_list *) obj->sysdep;
  261:       obj->sysdep = (void *) psl;
  262:     }
  263: }
  264: 
  265: #endif /* ! defined (HAVE_WAITPID) */
  266: #endif /* ! defined (HAVE_WAIT4) */
  267: 
  268: static void pex_child_error (struct pex_obj *, const char *, const char *, int)
  269:      ATTRIBUTE_NORETURN;
  270: static int pex_unix_open_read (struct pex_obj *, const char *, int);
  271: static int pex_unix_open_write (struct pex_obj *, const char *, int);
  272: static long pex_unix_exec_child (struct pex_obj *, int, const char *,
  273:                                  char * const *, char * const *,
  274:                                  int, int, int, int,
  275:                                  const char **, int *);
  276: static int pex_unix_close (struct pex_obj *, int);
  277: static int pex_unix_wait (struct pex_obj *, long, int *, struct pex_time *,
  278:                           int, const char **, int *);
  279: static int pex_unix_pipe (struct pex_obj *, int *, int);
  280: static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
  281: static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
  282: static void pex_unix_cleanup (struct pex_obj *);
  283: 
  284: /* The list of functions we pass to the common routines.  */
  285: 
  286: const struct pex_funcs funcs =
  287: {
  288:   pex_unix_open_read,
  289:   pex_unix_open_write,
  290:   pex_unix_exec_child,
  291:   pex_unix_close,
  292:   pex_unix_wait,
  293:   pex_unix_pipe,
  294:   pex_unix_fdopenr,
  295:   pex_unix_fdopenw,
  296:   pex_unix_cleanup
  297: };
  298: 
  299: /* Return a newly initialized pex_obj structure.  */
  300: 
  301: struct pex_obj *
  302: pex_init (int flags, const char *pname, const char *tempbase)
  303: {
  304:   return pex_init_common (flags, pname, tempbase, &funcs);
  305: }
  306: 
  307: /* Open a file for reading.  */
  308: 
  309: static int
  310: pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
  311:                     int binary ATTRIBUTE_UNUSED)
  312: {
  313:   return open (name, O_RDONLY);
  314: }
  315: 
  316: /* Open a file for writing.  */
  317: 
  318: static int
  319: pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
  320:                      int binary ATTRIBUTE_UNUSED)
  321: {
  322:   /* Note that we can't use O_EXCL here because gcc may have already
  323:      created the temporary file via make_temp_file.  */
  324:   return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE);
  325: }
  326: 
  327: /* Close a file.  */
  328: 
  329: static int
  330: pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
  331: {
  332:   return close (fd);
  333: }
  334: 
  335: /* Report an error from a child process.  We don't use stdio routines,
  336:    because we might be here due to a vfork call.  */
  337: 
  338: static void
  339: pex_child_error (struct pex_obj *obj, const char *executable,
  340:                  const char *errmsg, int err)
  341: {
  342: #define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s))
  343:   writeerr (obj->pname);
  344:   writeerr (": error trying to exec '");
  345:   writeerr (executable);
  346:   writeerr ("': ");
  347:   writeerr (errmsg);
  348:   writeerr (": ");
  349:   writeerr (xstrerror (err));
  350:   writeerr ("\n");
  351:   _exit (-1);
  352: }
  353: 
  354: /* Execute a child.  */
  355: 
  356: extern char **environ;
  357: 
  358: static long
  359: pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
  360:                      char * const * argv, char * const * env,
  361:                      int in, int out, int errdes,
  362:                      int toclose, const char **errmsg, int *err)
  363: {
  364:   pid_t pid;
  365: 
  366:   /* We declare these to be volatile to avoid warnings from gcc about
  367:      them being clobbered by vfork.  */
  368:   volatile int sleep_interval;
  369:   volatile int retries;
  370: 
  371:   sleep_interval = 1;
  372:   pid = -1;
  373:   for (retries = 0; retries < 4; ++retries)
  374:     {
  375:       pid = vfork ();
  376:       if (pid >= 0)
  377:         break;
  378:       sleep (sleep_interval);
  379:       sleep_interval *= 2;
  380:     }
  381: 
  382:   switch (pid)
  383:     {
  384:     case -1:
  385:       *err = errno;
  386:       *errmsg = VFORK_STRING;
  387:       return -1;
  388: 
  389:     case 0:
  390:       /* Child process.  */
  391:       if (in != STDIN_FILE_NO)
  392:         {
  393:           if (dup2 (in, STDIN_FILE_NO) < 0)
  394:             pex_child_error (obj, executable, "dup2", errno);
  395:           if (close (in) < 0)
  396:             pex_child_error (obj, executable, "close", errno);
  397:         }
  398:       if (out != STDOUT_FILE_NO)
  399:         {
  400:           if (dup2 (out, STDOUT_FILE_NO) < 0)
  401:             pex_child_error (obj, executable, "dup2", errno);
  402:           if (close (out) < 0)
  403:             pex_child_error (obj, executable, "close", errno);
  404:         }
  405:       if (errdes != STDERR_FILE_NO)
  406:         {
  407:           if (dup2 (errdes, STDERR_FILE_NO) < 0)
  408:             pex_child_error (obj, executable, "dup2", errno);
  409:           if (close (errdes) < 0)
  410:             pex_child_error (obj, executable, "close", errno);
  411:         }
  412:       if (toclose >= 0)
  413:         {
  414:           if (close (toclose) < 0)
  415:             pex_child_error (obj, executable, "close", errno);
  416:         }
  417:       if ((flags & PEX_STDERR_TO_STDOUT) != 0)
  418:         {
  419:           if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
  420:             pex_child_error (obj, executable, "dup2", errno);
  421:         }
  422: 
  423:       if (env)
  424:         environ = (char**) env;
  425: 
  426:       if ((flags & PEX_SEARCH) != 0)
  427:         {
  428:           execvp (executable, argv);
  429:           pex_child_error (obj, executable, "execvp", errno);
  430:         }
  431:       else
  432:         {
  433:           execv (executable, argv);
  434:           pex_child_error (obj, executable, "execv", errno);
  435:         }
  436: 
  437:       /* NOTREACHED */
  438:       return -1;
  439: 
  440:     default:
  441:       /* Parent process.  */
  442:       if (in != STDIN_FILE_NO)
  443:         {
  444:           if (close (in) < 0)
  445:             {
  446:               *err = errno;
  447:               *errmsg = "close";
  448:               return -1;
  449:             }
  450:         }
  451:       if (out != STDOUT_FILE_NO)
  452:         {
  453:           if (close (out) < 0)
  454:             {
  455:               *err = errno;
  456:               *errmsg = "close";
  457:               return -1;
  458:             }
  459:         }
  460:       if (errdes != STDERR_FILE_NO)
  461:         {
  462:           if (close (errdes) < 0)
  463:             {
  464:               *err = errno;
  465:               *errmsg = "close";
  466:               return -1;
  467:             }
  468:         }
  469: 
  470:       return (long) pid;
  471:     }
  472: }
  473: 
  474: /* Wait for a child process to complete.  */
  475: 
  476: static int
  477: pex_unix_wait (struct pex_obj *obj, long pid, int *status,
  478:                struct pex_time *time, int done, const char **errmsg,
  479:                int *err)
  480: {
  481:   /* If we are cleaning up when the caller didn't retrieve process
  482:      status for some reason, encourage the process to go away.  */
  483:   if (done)
  484:     kill (pid, SIGTERM);
  485: 
  486:   if (pex_wait (obj, pid, status, time) < 0)
  487:     {
  488:       *err = errno;
  489:       *errmsg = "wait";
  490:       return -1;
  491:     }
  492: 
  493:   return 0;
  494: }
  495: 
  496: /* Create a pipe.  */
  497: 
  498: static int
  499: pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
  500:                int binary ATTRIBUTE_UNUSED)
  501: {
  502:   return pipe (p);
  503: }
  504: 
  505: /* Get a FILE pointer to read from a file descriptor.  */
  506: 
  507: static FILE *
  508: pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
  509:                   int binary ATTRIBUTE_UNUSED)
  510: {
  511:   return fdopen (fd, "r");
  512: }
  513: 
  514: static FILE *
  515: pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
  516:                   int binary ATTRIBUTE_UNUSED)
  517: {
  518:   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
  519:     return NULL;
  520:   return fdopen (fd, "w");
  521: }
  522: 
  523: static void
  524: pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
  525: {
  526: #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
  527:   while (obj->sysdep != NULL)
  528:     {
  529:       struct status_list *this;
  530:       struct status_list *next;
  531: 
  532:       this = (struct status_list *) obj->sysdep;
  533:       next = this->next;
  534:       free (this);
  535:       obj->sysdep = (void *) next;
  536:     }
  537: #endif
  538: }
1
Syntax (Markdown)