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