1 /* Utilities to execute a program in a subprocess (possibly linked by pipes 2 with other subprocesses), and wait for it. Generic Unix version 3 (also used for UWIN and VMS). 4 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009 5 Free Software Foundation, Inc. 6 7 This file is part of the libiberty library. 8 Libiberty is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public 10 License as published by the Free Software Foundation; either 11 version 2 of the License, or (at your option) any later version. 12 13 Libiberty is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Library General Public License for more details. 17 18 You should have received a copy of the GNU Library General Public 19 License along with libiberty; see the file COPYING.LIB. If not, 20 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 21 Boston, MA 02110-1301, USA. */ 22 23 #include "config.h" 24 #include "libiberty.h" 25 #include "pex-common.h" 26 27 #include <stdio.h> 28 #include <signal.h> 29 #include <errno.h> 30 #ifdef NEED_DECLARATION_ERRNO 31 extern int errno; 32 #endif 33 #ifdef HAVE_STDLIB_H 34 #include <stdlib.h> 35 #endif 36 #ifdef HAVE_STRING_H 37 #include <string.h> 38 #endif 39 #ifdef HAVE_UNISTD_H 40 #include <unistd.h> 41 #endif 42 43 #include <sys/types.h> 44 45 #ifdef HAVE_FCNTL_H 46 #include <fcntl.h> 47 #endif 48 #ifdef HAVE_SYS_WAIT_H 49 #include <sys/wait.h> 50 #endif 51 #ifdef HAVE_GETRUSAGE 52 #include <sys/time.h> 53 #include <sys/resource.h> 54 #endif 55 #ifdef HAVE_SYS_STAT_H 56 #include <sys/stat.h> 57 #endif 58 59 60 #ifdef vfork /* Autoconf may define this to fork for us. */ 61 # define VFORK_STRING "fork" 62 #else 63 # define VFORK_STRING "vfork" 64 #endif 65 #ifdef HAVE_VFORK_H 66 #include <vfork.h> 67 #endif 68 #if defined(VMS) && defined (__LONG_POINTERS) 69 #ifndef __CHAR_PTR32 70 typedef char * __char_ptr32 71 __attribute__ ((mode (SI))); 72 #endif 73 74 typedef __char_ptr32 *__char_ptr_char_ptr32 75 __attribute__ ((mode (SI))); 76 77 /* Return a 32 bit pointer to an array of 32 bit pointers 78 given a 64 bit pointer to an array of 64 bit pointers. */ 79 80 static __char_ptr_char_ptr32 81 to_ptr32 (char **ptr64) 82 { 83 int argc; 84 __char_ptr_char_ptr32 short_argv; 85 86 for (argc=0; ptr64[argc]; argc++); 87 88 /* Reallocate argv with 32 bit pointers. */ 89 short_argv = (__char_ptr_char_ptr32) decc$malloc 90 (sizeof (__char_ptr32) * (argc + 1)); 91 92 for (argc=0; ptr64[argc]; argc++) 93 short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]); 94 95 short_argv[argc] = (__char_ptr32) 0; 96 return short_argv; 97 98 } 99 #else 100 #define to_ptr32(argv) argv 101 #endif 102 103 /* File mode to use for private and world-readable files. */ 104 105 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) 106 #define PUBLIC_MODE \ 107 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 108 #else 109 #define PUBLIC_MODE 0666 110 #endif 111 112 /* Get the exit status of a particular process, and optionally get the 113 time that it took. This is simple if we have wait4, slightly 114 harder if we have waitpid, and is a pain if we only have wait. */ 115 116 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); 117 118 #ifdef HAVE_WAIT4 119 120 static pid_t 121 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 122 struct pex_time *time) 123 { 124 pid_t ret; 125 struct rusage r; 126 127 #ifdef HAVE_WAITPID 128 if (time == NULL) 129 return waitpid (pid, status, 0); 130 #endif 131 132 ret = wait4 (pid, status, 0, &r); 133 134 if (time != NULL) 135 { 136 time->user_seconds = r.ru_utime.tv_sec; 137 time->user_microseconds= r.ru_utime.tv_usec; 138 time->system_seconds = r.ru_stime.tv_sec; 139 time->system_microseconds= r.ru_stime.tv_usec; 140 } 141 142 return ret; 143 } 144 145 #else /* ! defined (HAVE_WAIT4) */ 146 147 #ifdef HAVE_WAITPID 148 149 #ifndef HAVE_GETRUSAGE 150 151 static pid_t 152 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 153 struct pex_time *time) 154 { 155 if (time != NULL) 156 memset (time, 0, sizeof (struct pex_time)); 157 return waitpid (pid, status, 0); 158 } 159 160 #else /* defined (HAVE_GETRUSAGE) */ 161 162 static pid_t 163 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 164 struct pex_time *time) 165 { 166 struct rusage r1, r2; 167 pid_t ret; 168 169 if (time == NULL) 170 return waitpid (pid, status, 0); 171 172 getrusage (RUSAGE_CHILDREN, &r1); 173 174 ret = waitpid (pid, status, 0); 175 if (ret < 0) 176 return ret; 177 178 getrusage (RUSAGE_CHILDREN, &r2); 179 180 time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 181 time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 182 if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) 183 { 184 --time->user_seconds; 185 time->user_microseconds += 1000000; 186 } 187 188 time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 189 time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 190 if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) 191 { 192 --time->system_seconds; 193 time->system_microseconds += 1000000; 194 } 195 196 return ret; 197 } 198 199 #endif /* defined (HAVE_GETRUSAGE) */ 200 201 #else /* ! defined (HAVE_WAITPID) */ 202 203 struct status_list 204 { 205 struct status_list *next; 206 pid_t pid; 207 int status; 208 struct pex_time time; 209 }; 210 211 static pid_t 212 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) 213 { 214 struct status_list **pp; 215 216 for (pp = (struct status_list **) &obj->sysdep; 217 *pp != NULL; 218 pp = &(*pp)->next) 219 { 220 if ((*pp)->pid == pid) 221 { 222 struct status_list *p; 223 224 p = *pp; 225 *status = p->status; 226 if (time != NULL) 227 *time = p->time; 228 *pp = p->next; 229 free (p); 230 return pid; 231 } 232 } 233 234 while (1) 235 { 236 pid_t cpid; 237 struct status_list *psl; 238 struct pex_time pt; 239 #ifdef HAVE_GETRUSAGE 240 struct rusage r1, r2; 241 #endif 242 243 if (time != NULL) 244 { 245 #ifdef HAVE_GETRUSAGE 246 getrusage (RUSAGE_CHILDREN, &r1); 247 #else 248 memset (&pt, 0, sizeof (struct pex_time)); 249 #endif 250 } 251 252 cpid = wait (status); 253 254 #ifdef HAVE_GETRUSAGE 255 if (time != NULL && cpid >= 0) 256 { 257 getrusage (RUSAGE_CHILDREN, &r2); 258 259 pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 260 pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 261 if (pt.user_microseconds < 0) 262 { 263 --pt.user_seconds; 264 pt.user_microseconds += 1000000; 265 } 266 267 pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 268 pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 269 if (pt.system_microseconds < 0) 270 { 271 --pt.system_seconds; 272 pt.system_microseconds += 1000000; 273 } 274 } 275 #endif 276 277 if (cpid < 0 || cpid == pid) 278 { 279 if (time != NULL) 280 *time = pt; 281 return cpid; 282 } 283 284 psl = XNEW (struct status_list); 285 psl->pid = cpid; 286 psl->status = *status; 287 if (time != NULL) 288 psl->time = pt; 289 psl->next = (struct status_list *) obj->sysdep; 290 obj->sysdep = (void *) psl; 291 } 292 } 293 294 #endif /* ! defined (HAVE_WAITPID) */ 295 #endif /* ! defined (HAVE_WAIT4) */ 296 297 static void pex_child_error (struct pex_obj *, const char *, const char *, int) 298 ATTRIBUTE_NORETURN; 299 static int pex_unix_open_read (struct pex_obj *, const char *, int); 300 static int pex_unix_open_write (struct pex_obj *, const char *, int); 301 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *, 302 char * const *, char * const *, 303 int, int, int, int, 304 const char **, int *); 305 static int pex_unix_close (struct pex_obj *, int); 306 static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, 307 int, const char **, int *); 308 static int pex_unix_pipe (struct pex_obj *, int *, int); 309 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); 310 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); 311 static void pex_unix_cleanup (struct pex_obj *); 312 313 /* The list of functions we pass to the common routines. */ 314 315 const struct pex_funcs funcs = 316 { 317 pex_unix_open_read, 318 pex_unix_open_write, 319 pex_unix_exec_child, 320 pex_unix_close, 321 pex_unix_wait, 322 pex_unix_pipe, 323 pex_unix_fdopenr, 324 pex_unix_fdopenw, 325 pex_unix_cleanup 326 }; 327 328 /* Return a newly initialized pex_obj structure. */ 329 330 struct pex_obj * 331 pex_init (int flags, const char *pname, const char *tempbase) 332 { 333 return pex_init_common (flags, pname, tempbase, &funcs); 334 } 335 336 /* Open a file for reading. */ 337 338 static int 339 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 340 int binary ATTRIBUTE_UNUSED) 341 { 342 return open (name, O_RDONLY); 343 } 344 345 /* Open a file for writing. */ 346 347 static int 348 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 349 int binary ATTRIBUTE_UNUSED) 350 { 351 /* Note that we can't use O_EXCL here because gcc may have already 352 created the temporary file via make_temp_file. */ 353 return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE); 354 } 355 356 /* Close a file. */ 357 358 static int 359 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) 360 { 361 return close (fd); 362 } 363 364 /* Report an error from a child process. We don't use stdio routines, 365 because we might be here due to a vfork call. */ 366 367 static void 368 pex_child_error (struct pex_obj *obj, const char *executable, 369 const char *errmsg, int err) 370 { 371 #define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s)) 372 writeerr (obj->pname); 373 writeerr (": error trying to exec '"); 374 writeerr (executable); 375 writeerr ("': "); 376 writeerr (errmsg); 377 writeerr (": "); 378 writeerr (xstrerror (err)); 379 writeerr ("\n"); 380 _exit (-1); 381 } 382 383 /* Execute a child. */ 384 385 extern char **environ; 386 387 static pid_t 388 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, 389 char * const * argv, char * const * env, 390 int in, int out, int errdes, 391 int toclose, const char **errmsg, int *err) 392 { 393 pid_t pid; 394 395 /* We declare these to be volatile to avoid warnings from gcc about 396 them being clobbered by vfork. */ 397 volatile int sleep_interval; 398 volatile int retries; 399 400 sleep_interval = 1; 401 pid = -1; 402 for (retries = 0; retries < 4; ++retries) 403 { 404 pid = vfork (); 405 if (pid >= 0) 406 break; 407 sleep (sleep_interval); 408 sleep_interval *= 2; 409 } 410 411 switch (pid) 412 { 413 case -1: 414 *err = errno; 415 *errmsg = VFORK_STRING; 416 return (pid_t) -1; 417 418 case 0: 419 /* Child process. */ 420 if (in != STDIN_FILE_NO) 421 { 422 if (dup2 (in, STDIN_FILE_NO) < 0) 423 pex_child_error (obj, executable, "dup2", errno); 424 if (close (in) < 0) 425 pex_child_error (obj, executable, "close", errno); 426 } 427 if (out != STDOUT_FILE_NO) 428 { 429 if (dup2 (out, STDOUT_FILE_NO) < 0) 430 pex_child_error (obj, executable, "dup2", errno); 431 if (close (out) < 0) 432 pex_child_error (obj, executable, "close", errno); 433 } 434 if (errdes != STDERR_FILE_NO) 435 { 436 if (dup2 (errdes, STDERR_FILE_NO) < 0) 437 pex_child_error (obj, executable, "dup2", errno); 438 if (close (errdes) < 0) 439 pex_child_error (obj, executable, "close", errno); 440 } 441 if (toclose >= 0) 442 { 443 if (close (toclose) < 0) 444 pex_child_error (obj, executable, "close", errno); 445 } 446 if ((flags & PEX_STDERR_TO_STDOUT) != 0) 447 { 448 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) 449 pex_child_error (obj, executable, "dup2", errno); 450 } 451 452 if (env) 453 environ = (char**) env; 454 455 if ((flags & PEX_SEARCH) != 0) 456 { 457 execvp (executable, to_ptr32 (argv)); 458 pex_child_error (obj, executable, "execvp", errno); 459 } 460 else 461 { 462 execv (executable, to_ptr32 (argv)); 463 pex_child_error (obj, executable, "execv", errno); 464 } 465 466 /* NOTREACHED */ 467 return (pid_t) -1; 468 469 default: 470 /* Parent process. */ 471 if (in != STDIN_FILE_NO) 472 { 473 if (close (in) < 0) 474 { 475 *err = errno; 476 *errmsg = "close"; 477 return (pid_t) -1; 478 } 479 } 480 if (out != STDOUT_FILE_NO) 481 { 482 if (close (out) < 0) 483 { 484 *err = errno; 485 *errmsg = "close"; 486 return (pid_t) -1; 487 } 488 } 489 if (errdes != STDERR_FILE_NO) 490 { 491 if (close (errdes) < 0) 492 { 493 *err = errno; 494 *errmsg = "close"; 495 return (pid_t) -1; 496 } 497 } 498 499 return pid; 500 } 501 } 502 503 /* Wait for a child process to complete. */ 504 505 static int 506 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status, 507 struct pex_time *time, int done, const char **errmsg, 508 int *err) 509 { 510 /* If we are cleaning up when the caller didn't retrieve process 511 status for some reason, encourage the process to go away. */ 512 if (done) 513 kill (pid, SIGTERM); 514 515 if (pex_wait (obj, pid, status, time) < 0) 516 { 517 *err = errno; 518 *errmsg = "wait"; 519 return -1; 520 } 521 522 return 0; 523 } 524 525 /* Create a pipe. */ 526 527 static int 528 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, 529 int binary ATTRIBUTE_UNUSED) 530 { 531 return pipe (p); 532 } 533 534 /* Get a FILE pointer to read from a file descriptor. */ 535 536 static FILE * 537 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 538 int binary ATTRIBUTE_UNUSED) 539 { 540 return fdopen (fd, "r"); 541 } 542 543 static FILE * 544 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 545 int binary ATTRIBUTE_UNUSED) 546 { 547 if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) 548 return NULL; 549 return fdopen (fd, "w"); 550 } 551 552 static void 553 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) 554 { 555 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) 556 while (obj->sysdep != NULL) 557 { 558 struct status_list *this; 559 struct status_list *next; 560 561 this = (struct status_list *) obj->sysdep; 562 next = this->next; 563 free (this); 564 obj->sysdep = (void *) next; 565 } 566 #endif 567 } 568