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