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 * 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 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 * 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 * 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 * 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 * 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 * 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 * 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 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 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 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 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