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