pex-common.c revision 1.3 1 1.1 mrg /* Common code for executing a program in a sub-process.
2 1.3 mrg Copyright (C) 2005, 2010 Free Software Foundation, Inc.
3 1.1 mrg Written by Ian Lance Taylor <ian (at) airs.com>.
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 #include "config.h"
22 1.1 mrg #include "libiberty.h"
23 1.1 mrg #include "pex-common.h"
24 1.1 mrg
25 1.1 mrg #include <stdio.h>
26 1.1 mrg #include <errno.h>
27 1.1 mrg #ifdef NEED_DECLARATION_ERRNO
28 1.1 mrg extern int errno;
29 1.1 mrg #endif
30 1.1 mrg #ifdef HAVE_STDLIB_H
31 1.1 mrg #include <stdlib.h>
32 1.1 mrg #endif
33 1.1 mrg #ifdef HAVE_STRING_H
34 1.1 mrg #include <string.h>
35 1.1 mrg #endif
36 1.1 mrg #ifdef HAVE_UNISTD_H
37 1.1 mrg #include <unistd.h>
38 1.1 mrg #endif
39 1.1 mrg
40 1.1 mrg extern int mkstemps (char *, int);
41 1.1 mrg
42 1.1 mrg /* This file contains subroutines for the program execution routines
43 1.1 mrg (pex_init, pex_run, etc.). This file is compiled on all
44 1.1 mrg systems. */
45 1.1 mrg
46 1.1 mrg static void pex_add_remove (struct pex_obj *, const char *, int);
47 1.1 mrg static int pex_get_status_and_time (struct pex_obj *, int, const char **,
48 1.1 mrg int *);
49 1.1 mrg
50 1.1 mrg /* Initialize a pex_obj structure. */
51 1.1 mrg
52 1.1 mrg struct pex_obj *
53 1.1 mrg pex_init_common (int flags, const char *pname, const char *tempbase,
54 1.1 mrg const struct pex_funcs *funcs)
55 1.1 mrg {
56 1.1 mrg struct pex_obj *obj;
57 1.1 mrg
58 1.1 mrg obj = XNEW (struct pex_obj);
59 1.1 mrg obj->flags = flags;
60 1.1 mrg obj->pname = pname;
61 1.1 mrg obj->tempbase = tempbase;
62 1.1 mrg obj->next_input = STDIN_FILE_NO;
63 1.1 mrg obj->next_input_name = NULL;
64 1.1 mrg obj->next_input_name_allocated = 0;
65 1.1 mrg obj->stderr_pipe = -1;
66 1.1 mrg obj->count = 0;
67 1.1 mrg obj->children = NULL;
68 1.1 mrg obj->status = NULL;
69 1.1 mrg obj->time = NULL;
70 1.1 mrg obj->number_waited = 0;
71 1.1 mrg obj->input_file = NULL;
72 1.1 mrg obj->read_output = NULL;
73 1.1 mrg obj->read_err = NULL;
74 1.1 mrg obj->remove_count = 0;
75 1.1 mrg obj->remove = NULL;
76 1.1 mrg obj->funcs = funcs;
77 1.1 mrg obj->sysdep = NULL;
78 1.1 mrg return obj;
79 1.1 mrg }
80 1.1 mrg
81 1.1 mrg /* Add a file to be removed when we are done. */
82 1.1 mrg
83 1.1 mrg static void
84 1.1 mrg pex_add_remove (struct pex_obj *obj, const char *name, int allocated)
85 1.1 mrg {
86 1.1 mrg char *add;
87 1.1 mrg
88 1.1 mrg ++obj->remove_count;
89 1.1 mrg obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count);
90 1.1 mrg if (allocated)
91 1.1 mrg add = (char *) name;
92 1.1 mrg else
93 1.1 mrg add = xstrdup (name);
94 1.1 mrg obj->remove[obj->remove_count - 1] = add;
95 1.1 mrg }
96 1.1 mrg
97 1.1 mrg /* Generate a temporary file name based on OBJ, FLAGS, and NAME.
98 1.1 mrg Return NULL if we were unable to reserve a temporary filename.
99 1.1 mrg
100 1.1 mrg If non-NULL, the result is either allocated with malloc, or the
101 1.1 mrg same pointer as NAME. */
102 1.1 mrg static char *
103 1.1 mrg temp_file (struct pex_obj *obj, int flags, char *name)
104 1.1 mrg {
105 1.1 mrg if (name == NULL)
106 1.1 mrg {
107 1.1 mrg if (obj->tempbase == NULL)
108 1.1 mrg {
109 1.1 mrg name = make_temp_file (NULL);
110 1.1 mrg }
111 1.1 mrg else
112 1.1 mrg {
113 1.1 mrg int len = strlen (obj->tempbase);
114 1.1 mrg int out;
115 1.1 mrg
116 1.1 mrg if (len >= 6
117 1.1 mrg && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0)
118 1.1 mrg name = xstrdup (obj->tempbase);
119 1.1 mrg else
120 1.1 mrg name = concat (obj->tempbase, "XXXXXX", NULL);
121 1.1 mrg
122 1.1 mrg out = mkstemps (name, 0);
123 1.1 mrg if (out < 0)
124 1.1 mrg {
125 1.1 mrg free (name);
126 1.1 mrg return NULL;
127 1.1 mrg }
128 1.1 mrg
129 1.1 mrg /* This isn't obj->funcs->close because we got the
130 1.1 mrg descriptor from mkstemps, not from a function in
131 1.1 mrg obj->funcs. Calling close here is just like what
132 1.1 mrg make_temp_file does. */
133 1.1 mrg close (out);
134 1.1 mrg }
135 1.1 mrg }
136 1.1 mrg else if ((flags & PEX_SUFFIX) != 0)
137 1.1 mrg {
138 1.1 mrg if (obj->tempbase == NULL)
139 1.1 mrg name = make_temp_file (name);
140 1.1 mrg else
141 1.1 mrg name = concat (obj->tempbase, name, NULL);
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg return name;
145 1.1 mrg }
146 1.1 mrg
147 1.1 mrg
148 1.1 mrg /* As for pex_run (), but permits the environment for the child process
149 1.1 mrg to be specified. */
150 1.1 mrg
151 1.1 mrg const char *
152 1.1 mrg pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
153 1.1 mrg char * const * argv, char * const * env,
154 1.1 mrg const char *orig_outname, const char *errname,
155 1.1 mrg int *err)
156 1.1 mrg {
157 1.1 mrg const char *errmsg;
158 1.1 mrg int in, out, errdes;
159 1.1 mrg char *outname;
160 1.1 mrg int outname_allocated;
161 1.1 mrg int p[2];
162 1.1 mrg int toclose;
163 1.1 mrg pid_t pid;
164 1.1 mrg
165 1.1 mrg in = -1;
166 1.1 mrg out = -1;
167 1.1 mrg errdes = -1;
168 1.1 mrg outname = (char *) orig_outname;
169 1.1 mrg outname_allocated = 0;
170 1.1 mrg
171 1.1 mrg /* If the user called pex_input_file, close the file now. */
172 1.1 mrg if (obj->input_file)
173 1.1 mrg {
174 1.1 mrg if (fclose (obj->input_file) == EOF)
175 1.1 mrg {
176 1.1 mrg errmsg = "closing pipeline input file";
177 1.1 mrg goto error_exit;
178 1.1 mrg }
179 1.1 mrg obj->input_file = NULL;
180 1.1 mrg }
181 1.1 mrg
182 1.1 mrg /* Set IN. */
183 1.1 mrg
184 1.1 mrg if (obj->next_input_name != NULL)
185 1.1 mrg {
186 1.1 mrg /* We have to make sure that the previous process has completed
187 1.1 mrg before we try to read the file. */
188 1.1 mrg if (!pex_get_status_and_time (obj, 0, &errmsg, err))
189 1.1 mrg goto error_exit;
190 1.1 mrg
191 1.1 mrg in = obj->funcs->open_read (obj, obj->next_input_name,
192 1.1 mrg (flags & PEX_BINARY_INPUT) != 0);
193 1.1 mrg if (in < 0)
194 1.1 mrg {
195 1.1 mrg *err = errno;
196 1.1 mrg errmsg = "open temporary file";
197 1.1 mrg goto error_exit;
198 1.1 mrg }
199 1.1 mrg if (obj->next_input_name_allocated)
200 1.1 mrg {
201 1.1 mrg free (obj->next_input_name);
202 1.1 mrg obj->next_input_name_allocated = 0;
203 1.1 mrg }
204 1.1 mrg obj->next_input_name = NULL;
205 1.1 mrg }
206 1.1 mrg else
207 1.1 mrg {
208 1.1 mrg in = obj->next_input;
209 1.1 mrg if (in < 0)
210 1.1 mrg {
211 1.1 mrg *err = 0;
212 1.1 mrg errmsg = "pipeline already complete";
213 1.1 mrg goto error_exit;
214 1.1 mrg }
215 1.1 mrg }
216 1.1 mrg
217 1.1 mrg /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME. */
218 1.1 mrg
219 1.1 mrg if ((flags & PEX_LAST) != 0)
220 1.1 mrg {
221 1.1 mrg if (outname == NULL)
222 1.1 mrg out = STDOUT_FILE_NO;
223 1.1 mrg else if ((flags & PEX_SUFFIX) != 0)
224 1.1 mrg {
225 1.1 mrg outname = concat (obj->tempbase, outname, NULL);
226 1.1 mrg outname_allocated = 1;
227 1.1 mrg }
228 1.1 mrg obj->next_input = -1;
229 1.1 mrg }
230 1.1 mrg else if ((obj->flags & PEX_USE_PIPES) == 0)
231 1.1 mrg {
232 1.1 mrg outname = temp_file (obj, flags, outname);
233 1.1 mrg if (! outname)
234 1.1 mrg {
235 1.1 mrg *err = 0;
236 1.1 mrg errmsg = "could not create temporary file";
237 1.1 mrg goto error_exit;
238 1.1 mrg }
239 1.1 mrg
240 1.1 mrg if (outname != orig_outname)
241 1.1 mrg outname_allocated = 1;
242 1.1 mrg
243 1.1 mrg if ((obj->flags & PEX_SAVE_TEMPS) == 0)
244 1.1 mrg {
245 1.1 mrg pex_add_remove (obj, outname, outname_allocated);
246 1.1 mrg outname_allocated = 0;
247 1.1 mrg }
248 1.1 mrg
249 1.1 mrg /* Hand off ownership of outname to the next stage. */
250 1.1 mrg obj->next_input_name = outname;
251 1.1 mrg obj->next_input_name_allocated = outname_allocated;
252 1.1 mrg outname_allocated = 0;
253 1.1 mrg }
254 1.1 mrg else
255 1.1 mrg {
256 1.1 mrg if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0)
257 1.1 mrg {
258 1.1 mrg *err = errno;
259 1.1 mrg errmsg = "pipe";
260 1.1 mrg goto error_exit;
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg out = p[WRITE_PORT];
264 1.1 mrg obj->next_input = p[READ_PORT];
265 1.1 mrg }
266 1.1 mrg
267 1.1 mrg if (out < 0)
268 1.1 mrg {
269 1.1 mrg out = obj->funcs->open_write (obj, outname,
270 1.1 mrg (flags & PEX_BINARY_OUTPUT) != 0);
271 1.1 mrg if (out < 0)
272 1.1 mrg {
273 1.1 mrg *err = errno;
274 1.1 mrg errmsg = "open temporary output file";
275 1.1 mrg goto error_exit;
276 1.1 mrg }
277 1.1 mrg }
278 1.1 mrg
279 1.1 mrg if (outname_allocated)
280 1.1 mrg {
281 1.1 mrg free (outname);
282 1.1 mrg outname_allocated = 0;
283 1.1 mrg }
284 1.1 mrg
285 1.1 mrg /* Set ERRDES. */
286 1.1 mrg
287 1.1 mrg if (errname != NULL && (flags & PEX_STDERR_TO_PIPE) != 0)
288 1.1 mrg {
289 1.1 mrg *err = 0;
290 1.1 mrg errmsg = "both ERRNAME and PEX_STDERR_TO_PIPE specified.";
291 1.1 mrg goto error_exit;
292 1.1 mrg }
293 1.1 mrg
294 1.1 mrg if (obj->stderr_pipe != -1)
295 1.1 mrg {
296 1.1 mrg *err = 0;
297 1.1 mrg errmsg = "PEX_STDERR_TO_PIPE used in the middle of pipeline";
298 1.1 mrg goto error_exit;
299 1.1 mrg }
300 1.1 mrg
301 1.1 mrg if (errname == NULL)
302 1.1 mrg {
303 1.1 mrg if (flags & PEX_STDERR_TO_PIPE)
304 1.1 mrg {
305 1.1 mrg if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_ERROR) != 0) < 0)
306 1.1 mrg {
307 1.1 mrg *err = errno;
308 1.1 mrg errmsg = "pipe";
309 1.1 mrg goto error_exit;
310 1.1 mrg }
311 1.1 mrg
312 1.1 mrg errdes = p[WRITE_PORT];
313 1.1 mrg obj->stderr_pipe = p[READ_PORT];
314 1.1 mrg }
315 1.1 mrg else
316 1.1 mrg {
317 1.1 mrg errdes = STDERR_FILE_NO;
318 1.1 mrg }
319 1.1 mrg }
320 1.1 mrg else
321 1.1 mrg {
322 1.1 mrg errdes = obj->funcs->open_write (obj, errname,
323 1.1 mrg (flags & PEX_BINARY_ERROR) != 0);
324 1.1 mrg if (errdes < 0)
325 1.1 mrg {
326 1.1 mrg *err = errno;
327 1.1 mrg errmsg = "open error file";
328 1.1 mrg goto error_exit;
329 1.1 mrg }
330 1.1 mrg }
331 1.1 mrg
332 1.1 mrg /* If we are using pipes, the child process has to close the next
333 1.1 mrg input pipe. */
334 1.1 mrg
335 1.1 mrg if ((obj->flags & PEX_USE_PIPES) == 0)
336 1.1 mrg toclose = -1;
337 1.1 mrg else
338 1.1 mrg toclose = obj->next_input;
339 1.1 mrg
340 1.1 mrg /* Run the program. */
341 1.1 mrg
342 1.1 mrg pid = obj->funcs->exec_child (obj, flags, executable, argv, env,
343 1.1 mrg in, out, errdes, toclose, &errmsg, err);
344 1.1 mrg if (pid < 0)
345 1.1 mrg goto error_exit;
346 1.1 mrg
347 1.1 mrg ++obj->count;
348 1.1 mrg obj->children = XRESIZEVEC (pid_t, obj->children, obj->count);
349 1.1 mrg obj->children[obj->count - 1] = pid;
350 1.1 mrg
351 1.1 mrg return NULL;
352 1.1 mrg
353 1.1 mrg error_exit:
354 1.1 mrg if (in >= 0 && in != STDIN_FILE_NO)
355 1.1 mrg obj->funcs->close (obj, in);
356 1.1 mrg if (out >= 0 && out != STDOUT_FILE_NO)
357 1.1 mrg obj->funcs->close (obj, out);
358 1.1 mrg if (errdes >= 0 && errdes != STDERR_FILE_NO)
359 1.1 mrg obj->funcs->close (obj, errdes);
360 1.1 mrg if (outname_allocated)
361 1.1 mrg free (outname);
362 1.1 mrg return errmsg;
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg /* Run a program. */
366 1.1 mrg
367 1.1 mrg const char *
368 1.1 mrg pex_run (struct pex_obj *obj, int flags, const char *executable,
369 1.1 mrg char * const * argv, const char *orig_outname, const char *errname,
370 1.1 mrg int *err)
371 1.1 mrg {
372 1.1 mrg return pex_run_in_environment (obj, flags, executable, argv, NULL,
373 1.1 mrg orig_outname, errname, err);
374 1.1 mrg }
375 1.1 mrg
376 1.1 mrg /* Return a FILE pointer for a temporary file to fill with input for
377 1.1 mrg the pipeline. */
378 1.1 mrg FILE *
379 1.1 mrg pex_input_file (struct pex_obj *obj, int flags, const char *in_name)
380 1.1 mrg {
381 1.1 mrg char *name = (char *) in_name;
382 1.1 mrg FILE *f;
383 1.1 mrg
384 1.1 mrg /* This must be called before the first pipeline stage is run, and
385 1.1 mrg there must not have been any other input selected. */
386 1.1 mrg if (obj->count != 0
387 1.1 mrg || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
388 1.1 mrg || obj->next_input_name)
389 1.1 mrg {
390 1.1 mrg errno = EINVAL;
391 1.1 mrg return NULL;
392 1.1 mrg }
393 1.1 mrg
394 1.1 mrg name = temp_file (obj, flags, name);
395 1.1 mrg if (! name)
396 1.1 mrg return NULL;
397 1.1 mrg
398 1.1 mrg f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w");
399 1.1 mrg if (! f)
400 1.1 mrg {
401 1.1 mrg free (name);
402 1.1 mrg return NULL;
403 1.1 mrg }
404 1.1 mrg
405 1.1 mrg obj->input_file = f;
406 1.1 mrg obj->next_input_name = name;
407 1.1 mrg obj->next_input_name_allocated = (name != in_name);
408 1.1 mrg
409 1.1 mrg return f;
410 1.1 mrg }
411 1.1 mrg
412 1.1 mrg /* Return a stream for a pipe connected to the standard input of the
413 1.1 mrg first stage of the pipeline. */
414 1.1 mrg FILE *
415 1.1 mrg pex_input_pipe (struct pex_obj *obj, int binary)
416 1.1 mrg {
417 1.1 mrg int p[2];
418 1.1 mrg FILE *f;
419 1.1 mrg
420 1.1 mrg /* You must call pex_input_pipe before the first pex_run or pex_one. */
421 1.1 mrg if (obj->count > 0)
422 1.1 mrg goto usage_error;
423 1.1 mrg
424 1.1 mrg /* You must be using pipes. Implementations that don't support
425 1.1 mrg pipes clear this flag before calling pex_init_common. */
426 1.1 mrg if (! (obj->flags & PEX_USE_PIPES))
427 1.1 mrg goto usage_error;
428 1.1 mrg
429 1.1 mrg /* If we have somehow already selected other input, that's a
430 1.1 mrg mistake. */
431 1.1 mrg if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
432 1.1 mrg || obj->next_input_name)
433 1.1 mrg goto usage_error;
434 1.1 mrg
435 1.1 mrg if (obj->funcs->pipe (obj, p, binary != 0) < 0)
436 1.1 mrg return NULL;
437 1.1 mrg
438 1.1 mrg f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
439 1.1 mrg if (! f)
440 1.1 mrg {
441 1.1 mrg int saved_errno = errno;
442 1.1 mrg obj->funcs->close (obj, p[READ_PORT]);
443 1.1 mrg obj->funcs->close (obj, p[WRITE_PORT]);
444 1.1 mrg errno = saved_errno;
445 1.1 mrg return NULL;
446 1.1 mrg }
447 1.1 mrg
448 1.1 mrg obj->next_input = p[READ_PORT];
449 1.1 mrg
450 1.1 mrg return f;
451 1.1 mrg
452 1.1 mrg usage_error:
453 1.1 mrg errno = EINVAL;
454 1.1 mrg return NULL;
455 1.1 mrg }
456 1.1 mrg
457 1.1 mrg /* Return a FILE pointer for the output of the last program
458 1.1 mrg executed. */
459 1.1 mrg
460 1.1 mrg FILE *
461 1.1 mrg pex_read_output (struct pex_obj *obj, int binary)
462 1.1 mrg {
463 1.1 mrg if (obj->next_input_name != NULL)
464 1.1 mrg {
465 1.1 mrg const char *errmsg;
466 1.1 mrg int err;
467 1.1 mrg
468 1.1 mrg /* We have to make sure that the process has completed before we
469 1.1 mrg try to read the file. */
470 1.1 mrg if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
471 1.1 mrg {
472 1.1 mrg errno = err;
473 1.1 mrg return NULL;
474 1.1 mrg }
475 1.1 mrg
476 1.1 mrg obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r");
477 1.1 mrg
478 1.1 mrg if (obj->next_input_name_allocated)
479 1.1 mrg {
480 1.1 mrg free (obj->next_input_name);
481 1.1 mrg obj->next_input_name_allocated = 0;
482 1.1 mrg }
483 1.1 mrg obj->next_input_name = NULL;
484 1.1 mrg }
485 1.1 mrg else
486 1.1 mrg {
487 1.1 mrg int o;
488 1.1 mrg
489 1.1 mrg o = obj->next_input;
490 1.1 mrg if (o < 0 || o == STDIN_FILE_NO)
491 1.1 mrg return NULL;
492 1.1 mrg obj->read_output = obj->funcs->fdopenr (obj, o, binary);
493 1.1 mrg obj->next_input = -1;
494 1.1 mrg }
495 1.1 mrg
496 1.1 mrg return obj->read_output;
497 1.1 mrg }
498 1.1 mrg
499 1.1 mrg FILE *
500 1.1 mrg pex_read_err (struct pex_obj *obj, int binary)
501 1.1 mrg {
502 1.1 mrg int o;
503 1.1 mrg
504 1.1 mrg o = obj->stderr_pipe;
505 1.1 mrg if (o < 0 || o == STDIN_FILE_NO)
506 1.1 mrg return NULL;
507 1.1 mrg obj->read_err = obj->funcs->fdopenr (obj, o, binary);
508 1.3 mrg obj->stderr_pipe = -1;
509 1.1 mrg return obj->read_err;
510 1.1 mrg }
511 1.1 mrg
512 1.1 mrg /* Get the exit status and, if requested, the resource time for all
513 1.1 mrg the child processes. Return 0 on failure, 1 on success. */
514 1.1 mrg
515 1.1 mrg static int
516 1.1 mrg pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg,
517 1.1 mrg int *err)
518 1.1 mrg {
519 1.1 mrg int ret;
520 1.1 mrg int i;
521 1.1 mrg
522 1.1 mrg if (obj->number_waited == obj->count)
523 1.1 mrg return 1;
524 1.1 mrg
525 1.1 mrg obj->status = XRESIZEVEC (int, obj->status, obj->count);
526 1.1 mrg if ((obj->flags & PEX_RECORD_TIMES) != 0)
527 1.1 mrg obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count);
528 1.1 mrg
529 1.1 mrg ret = 1;
530 1.1 mrg for (i = obj->number_waited; i < obj->count; ++i)
531 1.1 mrg {
532 1.1 mrg if (obj->funcs->wait (obj, obj->children[i], &obj->status[i],
533 1.1 mrg obj->time == NULL ? NULL : &obj->time[i],
534 1.1 mrg done, errmsg, err) < 0)
535 1.1 mrg ret = 0;
536 1.1 mrg }
537 1.1 mrg obj->number_waited = i;
538 1.1 mrg
539 1.1 mrg return ret;
540 1.1 mrg }
541 1.1 mrg
542 1.1 mrg /* Get exit status of executed programs. */
543 1.1 mrg
544 1.1 mrg int
545 1.1 mrg pex_get_status (struct pex_obj *obj, int count, int *vector)
546 1.1 mrg {
547 1.1 mrg if (obj->status == NULL)
548 1.1 mrg {
549 1.1 mrg const char *errmsg;
550 1.1 mrg int err;
551 1.1 mrg
552 1.1 mrg if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
553 1.1 mrg return 0;
554 1.1 mrg }
555 1.1 mrg
556 1.1 mrg if (count > obj->count)
557 1.1 mrg {
558 1.1 mrg memset (vector + obj->count, 0, (count - obj->count) * sizeof (int));
559 1.1 mrg count = obj->count;
560 1.1 mrg }
561 1.1 mrg
562 1.1 mrg memcpy (vector, obj->status, count * sizeof (int));
563 1.1 mrg
564 1.1 mrg return 1;
565 1.1 mrg }
566 1.1 mrg
567 1.1 mrg /* Get process times of executed programs. */
568 1.1 mrg
569 1.1 mrg int
570 1.1 mrg pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector)
571 1.1 mrg {
572 1.1 mrg if (obj->status == NULL)
573 1.1 mrg {
574 1.1 mrg const char *errmsg;
575 1.1 mrg int err;
576 1.1 mrg
577 1.1 mrg if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
578 1.1 mrg return 0;
579 1.1 mrg }
580 1.1 mrg
581 1.1 mrg if (obj->time == NULL)
582 1.1 mrg return 0;
583 1.1 mrg
584 1.1 mrg if (count > obj->count)
585 1.1 mrg {
586 1.1 mrg memset (vector + obj->count, 0,
587 1.1 mrg (count - obj->count) * sizeof (struct pex_time));
588 1.1 mrg count = obj->count;
589 1.1 mrg }
590 1.1 mrg
591 1.1 mrg memcpy (vector, obj->time, count * sizeof (struct pex_time));
592 1.1 mrg
593 1.1 mrg return 1;
594 1.1 mrg }
595 1.1 mrg
596 1.1 mrg /* Free a pex_obj structure. */
597 1.1 mrg
598 1.1 mrg void
599 1.1 mrg pex_free (struct pex_obj *obj)
600 1.1 mrg {
601 1.3 mrg /* Close pipe file descriptors corresponding to child's stdout and
602 1.3 mrg stderr so that the child does not hang trying to output something
603 1.3 mrg while we're waiting for it. */
604 1.1 mrg if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
605 1.1 mrg obj->funcs->close (obj, obj->next_input);
606 1.3 mrg if (obj->stderr_pipe >= 0 && obj->stderr_pipe != STDIN_FILE_NO)
607 1.3 mrg obj->funcs->close (obj, obj->stderr_pipe);
608 1.3 mrg if (obj->read_output != NULL)
609 1.3 mrg fclose (obj->read_output);
610 1.3 mrg if (obj->read_err != NULL)
611 1.3 mrg fclose (obj->read_err);
612 1.1 mrg
613 1.1 mrg /* If the caller forgot to wait for the children, we do it here, to
614 1.1 mrg avoid zombies. */
615 1.1 mrg if (obj->status == NULL)
616 1.1 mrg {
617 1.1 mrg const char *errmsg;
618 1.1 mrg int err;
619 1.1 mrg
620 1.1 mrg obj->flags &= ~ PEX_RECORD_TIMES;
621 1.1 mrg pex_get_status_and_time (obj, 1, &errmsg, &err);
622 1.1 mrg }
623 1.1 mrg
624 1.1 mrg if (obj->next_input_name_allocated)
625 1.1 mrg free (obj->next_input_name);
626 1.3 mrg free (obj->children);
627 1.3 mrg free (obj->status);
628 1.3 mrg free (obj->time);
629 1.1 mrg
630 1.1 mrg if (obj->remove_count > 0)
631 1.1 mrg {
632 1.1 mrg int i;
633 1.1 mrg
634 1.1 mrg for (i = 0; i < obj->remove_count; ++i)
635 1.1 mrg {
636 1.1 mrg remove (obj->remove[i]);
637 1.1 mrg free (obj->remove[i]);
638 1.1 mrg }
639 1.1 mrg free (obj->remove);
640 1.1 mrg }
641 1.1 mrg
642 1.1 mrg if (obj->funcs->cleanup != NULL)
643 1.1 mrg obj->funcs->cleanup (obj);
644 1.1 mrg
645 1.1 mrg free (obj);
646 1.1 mrg }
647