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/* Run a program. */ 146 147const char * 148pex_run (struct pex_obj *obj, int flags, const char *executable, 149 char * const * argv, const char *orig_outname, const char *errname, 150 int *err) 151{ 152 const char *errmsg; 153 int in, out, errdes; 154 char *outname; 155 int outname_allocated; 156 int p[2]; 157 long pid; 158 159 in = -1; 160 out = -1; 161 errdes = -1; 162 outname = (char *) orig_outname; 163 outname_allocated = 0; 164 165 /* If the user called pex_input_file, close the file now. */ 166 if (obj->input_file) 167 { 168 if (fclose (obj->input_file) == EOF) 169 { 170 errmsg = "closing pipeline input file"; 171 goto error_exit; 172 } 173 obj->input_file = NULL; 174 } 175 176 /* Set IN. */ 177 178 if (obj->next_input_name != NULL) 179 { 180 /* We have to make sure that the previous process has completed 181 before we try to read the file. */ 182 if (!pex_get_status_and_time (obj, 0, &errmsg, err)) 183 goto error_exit; 184 185 in = obj->funcs->open_read (obj, obj->next_input_name, 186 (flags & PEX_BINARY_INPUT) != 0); 187 if (in < 0) 188 { 189 *err = errno; 190 errmsg = "open temporary file"; 191 goto error_exit; 192 } 193 if (obj->next_input_name_allocated) 194 { 195 free (obj->next_input_name); 196 obj->next_input_name_allocated = 0; 197 } 198 obj->next_input_name = NULL; 199 } 200 else 201 { 202 in = obj->next_input; 203 if (in < 0) 204 { 205 *err = 0; 206 errmsg = "pipeline already complete"; 207 goto error_exit; 208 } 209 } 210 211 /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME. */ 212 213 if ((flags & PEX_LAST) != 0) 214 { 215 if (outname == NULL) 216 out = STDOUT_FILE_NO; 217 else if ((flags & PEX_SUFFIX) != 0) 218 { 219 outname = concat (obj->tempbase, outname, NULL); 220 outname_allocated = 1; 221 } 222 obj->next_input = -1; 223 } 224 else if ((obj->flags & PEX_USE_PIPES) == 0) 225 { 226 outname = temp_file (obj, flags, outname); 227 if (! outname) 228 { 229 *err = 0; 230 errmsg = "could not create temporary file"; 231 goto error_exit; 232 } 233 234 if (outname != orig_outname) 235 outname_allocated = 1; 236 237 if ((obj->flags & PEX_SAVE_TEMPS) == 0) 238 { 239 pex_add_remove (obj, outname, outname_allocated); 240 outname_allocated = 0; 241 } 242 243 /* Hand off ownership of outname to the next stage. */ 244 obj->next_input_name = outname; 245 obj->next_input_name_allocated = outname_allocated; 246 outname_allocated = 0; 247 } 248 else 249 { 250 if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0) 251 { 252 *err = errno; 253 errmsg = "pipe"; 254 goto error_exit; 255 } 256 257 out = p[WRITE_PORT]; 258 obj->next_input = p[READ_PORT]; 259 } 260 261 if (out < 0) 262 { 263 out = obj->funcs->open_write (obj, outname, 264 (flags & PEX_BINARY_OUTPUT) != 0); 265 if (out < 0) 266 { 267 *err = errno; 268 errmsg = "open temporary output file"; 269 goto error_exit; 270 } 271 } 272 273 if (outname_allocated) 274 { 275 free (outname); 276 outname_allocated = 0; 277 } 278 279 /* Set ERRDES. */ 280 281 if (errname == NULL) 282 errdes = STDERR_FILE_NO; 283 else 284 { 285 /* We assume that stderr is in text mode--it certainly shouldn't 286 be controlled by PEX_BINARY_OUTPUT. If necessary, we can add 287 a PEX_BINARY_STDERR flag. */ 288 errdes = obj->funcs->open_write (obj, errname, 0); 289 if (errdes < 0) 290 { 291 *err = errno; 292 errmsg = "open error file"; 293 goto error_exit; 294 } 295 } 296 297 /* Run the program. */ 298 299 pid = obj->funcs->exec_child (obj, flags, executable, argv, in, out, errdes, 300 &errmsg, err); 301 if (pid < 0) 302 goto error_exit; 303 304 ++obj->count; 305 obj->children = XRESIZEVEC (long, obj->children, obj->count); 306 obj->children[obj->count - 1] = pid; 307 308 return NULL; 309 310 error_exit: 311 if (in >= 0 && in != STDIN_FILE_NO) 312 obj->funcs->close (obj, in); 313 if (out >= 0 && out != STDOUT_FILE_NO) 314 obj->funcs->close (obj, out); 315 if (errdes >= 0 && errdes != STDERR_FILE_NO) 316 obj->funcs->close (obj, errdes); 317 if (outname_allocated) 318 free (outname); 319 return errmsg; 320} 321 322/* Return a FILE pointer for a temporary file to fill with input for 323 the pipeline. */ 324FILE * 325pex_input_file (struct pex_obj *obj, int flags, const char *in_name) 326{ 327 char *name = (char *) in_name; 328 FILE *f; 329 330 /* This must be called before the first pipeline stage is run, and 331 there must not have been any other input selected. */ 332 if (obj->count != 0 333 || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) 334 || obj->next_input_name) 335 { 336 errno = EINVAL; 337 return NULL; 338 } 339 340 name = temp_file (obj, flags, name); 341 if (! name) 342 return NULL; 343 344 f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w"); 345 if (! f) 346 { 347 free (name); 348 return NULL; 349 } 350 351 obj->input_file = f; 352 obj->next_input_name = name; 353 obj->next_input_name_allocated = (name != in_name); 354 355 return f; 356} 357 358/* Return a stream for a pipe connected to the standard input of the 359 first stage of the pipeline. */ 360FILE * 361pex_input_pipe (struct pex_obj *obj, int binary) 362{ 363 int p[2]; 364 FILE *f; 365 366 /* You must call pex_input_pipe before the first pex_run or pex_one. */ 367 if (obj->count > 0) 368 goto usage_error; 369 370 /* You must be using pipes. Implementations that don't support 371 pipes clear this flag before calling pex_init_common. */ 372 if (! (obj->flags & PEX_USE_PIPES)) 373 goto usage_error; 374 375 /* If we have somehow already selected other input, that's a 376 mistake. */ 377 if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) 378 || obj->next_input_name) 379 goto usage_error; 380 381 if (obj->funcs->pipe (obj, p, binary != 0) < 0) 382 return NULL; 383 384 f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0); 385 if (! f) 386 { 387 int saved_errno = errno; 388 obj->funcs->close (obj, p[READ_PORT]); 389 obj->funcs->close (obj, p[WRITE_PORT]); 390 errno = saved_errno; 391 return NULL; 392 } 393 394 obj->next_input = p[READ_PORT]; 395 396 return f; 397 398 usage_error: 399 errno = EINVAL; 400 return NULL; 401} 402 403/* Return a FILE pointer for the output of the last program 404 executed. */ 405 406FILE * 407pex_read_output (struct pex_obj *obj, int binary) 408{ 409 if (obj->next_input_name != NULL) 410 { 411 const char *errmsg; 412 int err; 413 414 /* We have to make sure that the process has completed before we 415 try to read the file. */ 416 if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) 417 { 418 errno = err; 419 return NULL; 420 } 421 422 obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r"); 423 424 if (obj->next_input_name_allocated) 425 { 426 free (obj->next_input_name); 427 obj->next_input_name_allocated = 0; 428 } 429 obj->next_input_name = NULL; 430 } 431 else 432 { 433 int o; 434 435 o = obj->next_input; 436 if (o < 0 || o == STDIN_FILE_NO) 437 return NULL; 438 obj->read_output = obj->funcs->fdopenr (obj, o, binary); 439 obj->next_input = -1; 440 } 441 442 return obj->read_output; 443} 444 445/* Get the exit status and, if requested, the resource time for all 446 the child processes. Return 0 on failure, 1 on success. */ 447 448static int 449pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg, 450 int *err) 451{ 452 int ret; 453 int i; 454 455 if (obj->number_waited == obj->count) 456 return 1; 457 458 obj->status = XRESIZEVEC (int, obj->status, obj->count); 459 if ((obj->flags & PEX_RECORD_TIMES) != 0) 460 obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count); 461 462 ret = 1; 463 for (i = obj->number_waited; i < obj->count; ++i) 464 { 465 if (obj->funcs->wait (obj, obj->children[i], &obj->status[i], 466 obj->time == NULL ? NULL : &obj->time[i], 467 done, errmsg, err) < 0) 468 ret = 0; 469 } 470 obj->number_waited = i; 471 472 return ret; 473} 474 475/* Get exit status of executed programs. */ 476 477int 478pex_get_status (struct pex_obj *obj, int count, int *vector) 479{ 480 if (obj->status == NULL) 481 { 482 const char *errmsg; 483 int err; 484 485 if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) 486 return 0; 487 } 488 489 if (count > obj->count) 490 { 491 memset (vector + obj->count, 0, (count - obj->count) * sizeof (int)); 492 count = obj->count; 493 } 494 495 memcpy (vector, obj->status, count * sizeof (int)); 496 497 return 1; 498} 499 500/* Get process times of executed programs. */ 501 502int 503pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector) 504{ 505 if (obj->status == NULL) 506 { 507 const char *errmsg; 508 int err; 509 510 if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) 511 return 0; 512 } 513 514 if (obj->time == NULL) 515 return 0; 516 517 if (count > obj->count) 518 { 519 memset (vector + obj->count, 0, 520 (count - obj->count) * sizeof (struct pex_time)); 521 count = obj->count; 522 } 523 524 memcpy (vector, obj->time, count * sizeof (struct pex_time)); 525 526 return 1; 527} 528 529/* Free a pex_obj structure. */ 530 531void 532pex_free (struct pex_obj *obj) 533{ 534 if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) 535 obj->funcs->close (obj, obj->next_input); 536 537 /* If the caller forgot to wait for the children, we do it here, to 538 avoid zombies. */ 539 if (obj->status == NULL) 540 { 541 const char *errmsg; 542 int err; 543 544 obj->flags &= ~ PEX_RECORD_TIMES; 545 pex_get_status_and_time (obj, 1, &errmsg, &err); 546 } 547 548 if (obj->next_input_name_allocated) 549 free (obj->next_input_name); 550 if (obj->children != NULL) 551 free (obj->children); 552 if (obj->status != NULL) 553 free (obj->status); 554 if (obj->time != NULL) 555 free (obj->time); 556 if (obj->read_output != NULL) 557 fclose (obj->read_output); 558 559 if (obj->remove_count > 0) 560 { 561 int i; 562 563 for (i = 0; i < obj->remove_count; ++i) 564 { 565 remove (obj->remove[i]); 566 free (obj->remove[i]); 567 } 568 free (obj->remove); 569 } 570 571 if (obj->funcs->cleanup != NULL) 572 obj->funcs->cleanup (obj); 573 574 free (obj); 575} 576