pexecute.c revision 1.11 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