Home | History | Annotate | Line # | Download | only in libiberty
      1      1.1     skrll /* Utilities to execute a program in a subprocess (possibly linked by pipes
      2      1.1     skrll    with other subprocesses), and wait for it.
      3  1.1.1.7  christos    Copyright (C) 2004-2026 Free Software Foundation, Inc.
      4      1.1     skrll 
      5      1.1     skrll This file is part of the libiberty library.
      6      1.1     skrll Libiberty is free software; you can redistribute it and/or
      7      1.1     skrll modify it under the terms of the GNU Library General Public
      8      1.1     skrll License as published by the Free Software Foundation; either
      9      1.1     skrll version 2 of the License, or (at your option) any later version.
     10      1.1     skrll 
     11      1.1     skrll Libiberty is distributed in the hope that it will be useful,
     12      1.1     skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1     skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14      1.1     skrll Library General Public License for more details.
     15      1.1     skrll 
     16      1.1     skrll You should have received a copy of the GNU Library General Public
     17      1.1     skrll License along with libiberty; see the file COPYING.LIB.  If not,
     18      1.1     skrll write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     19      1.1     skrll Boston, MA 02110-1301, USA.  */
     20      1.1     skrll 
     21      1.1     skrll /* pexecute is an old routine.  This implementation uses the newer
     22      1.1     skrll    pex_init/pex_run/pex_get_status/pex_free routines.  Don't use
     23      1.1     skrll    pexecute in new code.  Use the newer routines instead.  */
     24      1.1     skrll 
     25      1.1     skrll #include "config.h"
     26      1.1     skrll #include "libiberty.h"
     27      1.1     skrll 
     28      1.1     skrll #ifdef HAVE_STDLIB_H
     29      1.1     skrll #include <stdlib.h>
     30      1.1     skrll #endif
     31      1.1     skrll 
     32      1.1     skrll /* We only permit a single pexecute chain to execute at a time.  This
     33      1.1     skrll    was always true anyhow, though it wasn't documented.  */
     34      1.1     skrll 
     35      1.1     skrll static struct pex_obj *pex;
     36      1.1     skrll static int idx;
     37      1.1     skrll 
     38      1.1     skrll int
     39      1.1     skrll pexecute (const char *program, char * const *argv, const char *pname,
     40      1.1     skrll 	  const char *temp_base, char **errmsg_fmt, char **errmsg_arg,
     41      1.1     skrll 	  int flags)
     42      1.1     skrll {
     43      1.1     skrll   const char *errmsg;
     44      1.1     skrll   int err;
     45      1.1     skrll 
     46      1.1     skrll   if ((flags & PEXECUTE_FIRST) != 0)
     47      1.1     skrll     {
     48      1.1     skrll       if (pex != NULL)
     49      1.1     skrll 	{
     50      1.1     skrll 	  *errmsg_fmt = (char *) "pexecute already in progress";
     51      1.1     skrll 	  *errmsg_arg = NULL;
     52      1.1     skrll 	  return -1;
     53      1.1     skrll 	}
     54      1.1     skrll       pex = pex_init (PEX_USE_PIPES, pname, temp_base);
     55      1.1     skrll       idx = 0;
     56      1.1     skrll     }
     57      1.1     skrll   else
     58      1.1     skrll     {
     59      1.1     skrll       if (pex == NULL)
     60      1.1     skrll 	{
     61      1.1     skrll 	  *errmsg_fmt = (char *) "pexecute not in progress";
     62      1.1     skrll 	  *errmsg_arg = NULL;
     63      1.1     skrll 	  return -1;
     64      1.1     skrll 	}
     65      1.1     skrll     }
     66      1.1     skrll 
     67      1.1     skrll   errmsg = pex_run (pex,
     68      1.1     skrll 		    (((flags & PEXECUTE_LAST) != 0 ? PEX_LAST : 0)
     69      1.1     skrll 		     | ((flags & PEXECUTE_SEARCH) != 0 ? PEX_SEARCH : 0)),
     70      1.1     skrll 		    program, argv, NULL, NULL, &err);
     71      1.1     skrll   if (errmsg != NULL)
     72      1.1     skrll     {
     73      1.1     skrll       *errmsg_fmt = (char *) errmsg;
     74      1.1     skrll       *errmsg_arg = NULL;
     75      1.1     skrll       return -1;
     76      1.1     skrll     }
     77      1.1     skrll 
     78      1.1     skrll   /* Instead of a PID, we just return a one-based index into the
     79      1.1     skrll      status values.  We avoid zero just because the old pexecute would
     80      1.1     skrll      never return it.  */
     81      1.1     skrll   return ++idx;
     82      1.1     skrll }
     83      1.1     skrll 
     84      1.1     skrll int
     85      1.1     skrll pwait (int pid, int *status, int flags ATTRIBUTE_UNUSED)
     86      1.1     skrll {
     87      1.1     skrll   /* The PID returned by pexecute is one-based.  */
     88      1.1     skrll   --pid;
     89      1.1     skrll 
     90      1.1     skrll   if (pex == NULL || pid < 0 || pid >= idx)
     91      1.1     skrll     return -1;
     92      1.1     skrll 
     93      1.1     skrll   if (pid == 0 && idx == 1)
     94      1.1     skrll     {
     95      1.1     skrll       if (!pex_get_status (pex, 1, status))
     96      1.1     skrll 	return -1;
     97      1.1     skrll     }
     98      1.1     skrll   else
     99      1.1     skrll     {
    100      1.1     skrll       int *vector;
    101      1.1     skrll 
    102      1.1     skrll       vector = XNEWVEC (int, idx);
    103      1.1     skrll       if (!pex_get_status (pex, idx, vector))
    104      1.1     skrll 	{
    105      1.1     skrll 	  free (vector);
    106      1.1     skrll 	  return -1;
    107      1.1     skrll 	}
    108      1.1     skrll       *status = vector[pid];
    109      1.1     skrll       free (vector);
    110      1.1     skrll     }
    111      1.1     skrll 
    112      1.1     skrll   /* Assume that we are done after the caller has retrieved the last
    113      1.1     skrll      exit status.  The original implementation did not require that
    114      1.1     skrll      the exit statuses be retrieved in order, but this implementation
    115      1.1     skrll      does.  */
    116      1.1     skrll   if (pid + 1 == idx)
    117      1.1     skrll     {
    118      1.1     skrll       pex_free (pex);
    119      1.1     skrll       pex = NULL;
    120      1.1     skrll       idx = 0;
    121      1.1     skrll     }
    122      1.1     skrll 
    123      1.1     skrll   return pid + 1;
    124      1.1     skrll }
    125