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