Back to index

cell-binutils  2.17cvs20070401
pexecute.c
Go to the documentation of this file.
00001 /* Utilities to execute a program in a subprocess (possibly linked by pipes
00002    with other subprocesses), and wait for it.
00003    Copyright (C) 2004 Free Software Foundation, Inc.
00004 
00005 This file is part of the libiberty library.
00006 Libiberty is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Library General Public
00008 License as published by the Free Software Foundation; either
00009 version 2 of the License, or (at your option) any later version.
00010 
00011 Libiberty is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Library General Public License for more details.
00015 
00016 You should have received a copy of the GNU Library General Public
00017 License along with libiberty; see the file COPYING.LIB.  If not,
00018 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019 Boston, MA 02110-1301, USA.  */
00020 
00021 /* pexecute is an old routine.  This implementation uses the newer
00022    pex_init/pex_run/pex_get_status/pex_free routines.  Don't use
00023    pexecute in new code.  Use the newer routines instead.  */
00024 
00025 #include "config.h"
00026 #include "libiberty.h"
00027 
00028 #ifdef HAVE_STDLIB_H
00029 #include <stdlib.h>
00030 #endif
00031 
00032 /* We only permit a single pexecute chain to execute at a time.  This
00033    was always true anyhow, though it wasn't documented.  */
00034 
00035 static struct pex_obj *pex;
00036 static int idx;
00037 
00038 int
00039 pexecute (const char *program, char * const *argv, const char *pname,
00040          const char *temp_base, char **errmsg_fmt, char **errmsg_arg,
00041          int flags)
00042 {
00043   const char *errmsg;
00044   int err;
00045 
00046   if ((flags & PEXECUTE_FIRST) != 0)
00047     {
00048       if (pex != NULL)
00049        {
00050          *errmsg_fmt = (char *) "pexecute already in progress";
00051          *errmsg_arg = NULL;
00052          return -1;
00053        }
00054       pex = pex_init (PEX_USE_PIPES, pname, temp_base);
00055       idx = 0;
00056     }
00057   else
00058     {
00059       if (pex == NULL)
00060        {
00061          *errmsg_fmt = (char *) "pexecute not in progress";
00062          *errmsg_arg = NULL;
00063          return -1;
00064        }
00065     }
00066 
00067   errmsg = pex_run (pex,
00068                   (((flags & PEXECUTE_LAST) != 0 ? PEX_LAST : 0)
00069                    | ((flags & PEXECUTE_SEARCH) != 0 ? PEX_SEARCH : 0)),
00070                   program, argv, NULL, NULL, &err);
00071   if (errmsg != NULL)
00072     {
00073       *errmsg_fmt = (char *) errmsg;
00074       *errmsg_arg = NULL;
00075       return -1;
00076     }
00077 
00078   /* Instead of a PID, we just return a one-based index into the
00079      status values.  We avoid zero just because the old pexecute would
00080      never return it.  */
00081   return ++idx;
00082 }
00083 
00084 int
00085 pwait (int pid, int *status, int flags ATTRIBUTE_UNUSED)
00086 {
00087   /* The PID returned by pexecute is one-based.  */
00088   --pid;
00089 
00090   if (pex == NULL || pid < 0 || pid >= idx)
00091     return -1;
00092 
00093   if (pid == 0 && idx == 1)
00094     {
00095       if (!pex_get_status (pex, 1, status))
00096        return -1;
00097     }
00098   else
00099     {
00100       int *vector;
00101 
00102       vector = XNEWVEC (int, idx);
00103       if (!pex_get_status (pex, idx, vector))
00104        {
00105          free (vector);
00106          return -1;
00107        }
00108       *status = vector[pid];
00109       free (vector);
00110     }
00111 
00112   /* Assume that we are done after the caller has retrieved the last
00113      exit status.  The original implementation did not require that
00114      the exit statuses be retrieved in order, but this implementation
00115      does.  */
00116   if (pid + 1 == idx)
00117     {
00118       pex_free (pex);
00119       pex = NULL;
00120       idx = 0;
00121     }
00122 
00123   return pid + 1;
00124 }