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