1169695Skan/* Utilities to execute a program in a subprocess (possibly linked by pipes 2169695Skan with other subprocesses), and wait for it. Generic Unix version 3169695Skan (also used for UWIN and VMS). 4169695Skan Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 5169695Skan Free Software Foundation, Inc. 6169695Skan 7169695SkanThis file is part of the libiberty library. 8169695SkanLibiberty is free software; you can redistribute it and/or 9169695Skanmodify it under the terms of the GNU Library General Public 10169695SkanLicense as published by the Free Software Foundation; either 11169695Skanversion 2 of the License, or (at your option) any later version. 12169695Skan 13169695SkanLibiberty is distributed in the hope that it will be useful, 14169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 15169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16169695SkanLibrary General Public License for more details. 17169695Skan 18169695SkanYou should have received a copy of the GNU Library General Public 19169695SkanLicense along with libiberty; see the file COPYING.LIB. If not, 20169695Skanwrite to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 21169695SkanBoston, MA 02110-1301, USA. */ 22169695Skan 23169695Skan#include "config.h" 24169695Skan#include "libiberty.h" 25169695Skan#include "pex-common.h" 26169695Skan 27169695Skan#include <stdio.h> 28169695Skan#include <signal.h> 29169695Skan#include <errno.h> 30169695Skan#ifdef NEED_DECLARATION_ERRNO 31169695Skanextern int errno; 32169695Skan#endif 33169695Skan#ifdef HAVE_STDLIB_H 34169695Skan#include <stdlib.h> 35169695Skan#endif 36169695Skan#ifdef HAVE_STRING_H 37169695Skan#include <string.h> 38169695Skan#endif 39169695Skan#ifdef HAVE_UNISTD_H 40169695Skan#include <unistd.h> 41169695Skan#endif 42169695Skan 43169695Skan#include <sys/types.h> 44169695Skan 45169695Skan#ifdef HAVE_FCNTL_H 46169695Skan#include <fcntl.h> 47169695Skan#endif 48169695Skan#ifdef HAVE_SYS_WAIT_H 49169695Skan#include <sys/wait.h> 50169695Skan#endif 51169695Skan#ifdef HAVE_GETRUSAGE 52169695Skan#include <sys/time.h> 53169695Skan#include <sys/resource.h> 54169695Skan#endif 55169695Skan#ifdef HAVE_SYS_STAT_H 56169695Skan#include <sys/stat.h> 57169695Skan#endif 58169695Skan 59169695Skan 60169695Skan#ifdef vfork /* Autoconf may define this to fork for us. */ 61169695Skan# define VFORK_STRING "fork" 62169695Skan#else 63169695Skan# define VFORK_STRING "vfork" 64169695Skan#endif 65169695Skan#ifdef HAVE_VFORK_H 66169695Skan#include <vfork.h> 67169695Skan#endif 68169695Skan#ifdef VMS 69169695Skan#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ 70169695Skan lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) 71169695Skan#endif /* VMS */ 72169695Skan 73169695Skan 74169695Skan/* File mode to use for private and world-readable files. */ 75169695Skan 76169695Skan#if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) 77169695Skan#define PUBLIC_MODE \ 78169695Skan (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 79169695Skan#else 80169695Skan#define PUBLIC_MODE 0666 81169695Skan#endif 82169695Skan 83169695Skan/* Get the exit status of a particular process, and optionally get the 84169695Skan time that it took. This is simple if we have wait4, slightly 85169695Skan harder if we have waitpid, and is a pain if we only have wait. */ 86169695Skan 87169695Skanstatic pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); 88169695Skan 89169695Skan#ifdef HAVE_WAIT4 90169695Skan 91169695Skanstatic pid_t 92169695Skanpex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 93169695Skan struct pex_time *time) 94169695Skan{ 95169695Skan pid_t ret; 96169695Skan struct rusage r; 97169695Skan 98169695Skan#ifdef HAVE_WAITPID 99169695Skan if (time == NULL) 100169695Skan return waitpid (pid, status, 0); 101169695Skan#endif 102169695Skan 103169695Skan ret = wait4 (pid, status, 0, &r); 104169695Skan 105169695Skan if (time != NULL) 106169695Skan { 107169695Skan time->user_seconds = r.ru_utime.tv_sec; 108169695Skan time->user_microseconds= r.ru_utime.tv_usec; 109169695Skan time->system_seconds = r.ru_stime.tv_sec; 110169695Skan time->system_microseconds= r.ru_stime.tv_usec; 111169695Skan } 112169695Skan 113169695Skan return ret; 114169695Skan} 115169695Skan 116169695Skan#else /* ! defined (HAVE_WAIT4) */ 117169695Skan 118169695Skan#ifdef HAVE_WAITPID 119169695Skan 120169695Skan#ifndef HAVE_GETRUSAGE 121169695Skan 122169695Skanstatic pid_t 123169695Skanpex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 124169695Skan struct pex_time *time) 125169695Skan{ 126169695Skan if (time != NULL) 127169695Skan memset (time, 0, sizeof (struct pex_time)); 128169695Skan return waitpid (pid, status, 0); 129169695Skan} 130169695Skan 131169695Skan#else /* defined (HAVE_GETRUSAGE) */ 132169695Skan 133169695Skanstatic pid_t 134169695Skanpex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 135169695Skan struct pex_time *time) 136169695Skan{ 137169695Skan struct rusage r1, r2; 138169695Skan pid_t ret; 139169695Skan 140169695Skan if (time == NULL) 141169695Skan return waitpid (pid, status, 0); 142169695Skan 143169695Skan getrusage (RUSAGE_CHILDREN, &r1); 144169695Skan 145169695Skan ret = waitpid (pid, status, 0); 146169695Skan if (ret < 0) 147169695Skan return ret; 148169695Skan 149169695Skan getrusage (RUSAGE_CHILDREN, &r2); 150169695Skan 151169695Skan time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 152169695Skan time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 153169695Skan if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) 154169695Skan { 155169695Skan --time->user_seconds; 156169695Skan time->user_microseconds += 1000000; 157169695Skan } 158169695Skan 159169695Skan time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 160169695Skan time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 161169695Skan if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) 162169695Skan { 163169695Skan --time->system_seconds; 164169695Skan time->system_microseconds += 1000000; 165169695Skan } 166169695Skan 167169695Skan return ret; 168169695Skan} 169169695Skan 170169695Skan#endif /* defined (HAVE_GETRUSAGE) */ 171169695Skan 172169695Skan#else /* ! defined (HAVE_WAITPID) */ 173169695Skan 174169695Skanstruct status_list 175169695Skan{ 176169695Skan struct status_list *next; 177169695Skan pid_t pid; 178169695Skan int status; 179169695Skan struct pex_time time; 180169695Skan}; 181169695Skan 182169695Skanstatic pid_t 183169695Skanpex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) 184169695Skan{ 185169695Skan struct status_list **pp; 186169695Skan 187169695Skan for (pp = (struct status_list **) &obj->sysdep; 188169695Skan *pp != NULL; 189169695Skan pp = &(*pp)->next) 190169695Skan { 191169695Skan if ((*pp)->pid == pid) 192169695Skan { 193169695Skan struct status_list *p; 194169695Skan 195169695Skan p = *pp; 196169695Skan *status = p->status; 197169695Skan if (time != NULL) 198169695Skan *time = p->time; 199169695Skan *pp = p->next; 200169695Skan free (p); 201169695Skan return pid; 202169695Skan } 203169695Skan } 204169695Skan 205169695Skan while (1) 206169695Skan { 207169695Skan pid_t cpid; 208169695Skan struct status_list *psl; 209169695Skan struct pex_time pt; 210169695Skan#ifdef HAVE_GETRUSAGE 211169695Skan struct rusage r1, r2; 212169695Skan#endif 213169695Skan 214169695Skan if (time != NULL) 215169695Skan { 216169695Skan#ifdef HAVE_GETRUSAGE 217169695Skan getrusage (RUSAGE_CHILDREN, &r1); 218169695Skan#else 219169695Skan memset (&pt, 0, sizeof (struct pex_time)); 220169695Skan#endif 221169695Skan } 222169695Skan 223169695Skan cpid = wait (status); 224169695Skan 225169695Skan#ifdef HAVE_GETRUSAGE 226169695Skan if (time != NULL && cpid >= 0) 227169695Skan { 228169695Skan getrusage (RUSAGE_CHILDREN, &r2); 229169695Skan 230169695Skan pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 231169695Skan pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 232169695Skan if (pt.user_microseconds < 0) 233169695Skan { 234169695Skan --pt.user_seconds; 235169695Skan pt.user_microseconds += 1000000; 236169695Skan } 237169695Skan 238169695Skan pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 239169695Skan pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 240169695Skan if (pt.system_microseconds < 0) 241169695Skan { 242169695Skan --pt.system_seconds; 243169695Skan pt.system_microseconds += 1000000; 244169695Skan } 245169695Skan } 246169695Skan#endif 247169695Skan 248169695Skan if (cpid < 0 || cpid == pid) 249169695Skan { 250169695Skan if (time != NULL) 251169695Skan *time = pt; 252169695Skan return cpid; 253169695Skan } 254169695Skan 255169695Skan psl = XNEW (struct status_list); 256169695Skan psl->pid = cpid; 257169695Skan psl->status = *status; 258169695Skan if (time != NULL) 259169695Skan psl->time = pt; 260169695Skan psl->next = (struct status_list *) obj->sysdep; 261169695Skan obj->sysdep = (void *) psl; 262169695Skan } 263169695Skan} 264169695Skan 265169695Skan#endif /* ! defined (HAVE_WAITPID) */ 266169695Skan#endif /* ! defined (HAVE_WAIT4) */ 267169695Skan 268169695Skanstatic void pex_child_error (struct pex_obj *, const char *, const char *, int) 269169695Skan ATTRIBUTE_NORETURN; 270169695Skanstatic int pex_unix_open_read (struct pex_obj *, const char *, int); 271169695Skanstatic int pex_unix_open_write (struct pex_obj *, const char *, int); 272169695Skanstatic long pex_unix_exec_child (struct pex_obj *, int, const char *, 273169695Skan char * const *, char * const *, 274169695Skan int, int, int, int, 275169695Skan const char **, int *); 276169695Skanstatic int pex_unix_close (struct pex_obj *, int); 277169695Skanstatic int pex_unix_wait (struct pex_obj *, long, int *, struct pex_time *, 278169695Skan int, const char **, int *); 279169695Skanstatic int pex_unix_pipe (struct pex_obj *, int *, int); 280169695Skanstatic FILE *pex_unix_fdopenr (struct pex_obj *, int, int); 281169695Skanstatic FILE *pex_unix_fdopenw (struct pex_obj *, int, int); 282169695Skanstatic void pex_unix_cleanup (struct pex_obj *); 283169695Skan 284169695Skan/* The list of functions we pass to the common routines. */ 285169695Skan 286169695Skanconst struct pex_funcs funcs = 287169695Skan{ 288169695Skan pex_unix_open_read, 289169695Skan pex_unix_open_write, 290169695Skan pex_unix_exec_child, 291169695Skan pex_unix_close, 292169695Skan pex_unix_wait, 293169695Skan pex_unix_pipe, 294169695Skan pex_unix_fdopenr, 295169695Skan pex_unix_fdopenw, 296169695Skan pex_unix_cleanup 297169695Skan}; 298169695Skan 299169695Skan/* Return a newly initialized pex_obj structure. */ 300169695Skan 301169695Skanstruct pex_obj * 302169695Skanpex_init (int flags, const char *pname, const char *tempbase) 303169695Skan{ 304169695Skan return pex_init_common (flags, pname, tempbase, &funcs); 305169695Skan} 306169695Skan 307169695Skan/* Open a file for reading. */ 308169695Skan 309169695Skanstatic int 310169695Skanpex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 311169695Skan int binary ATTRIBUTE_UNUSED) 312169695Skan{ 313169695Skan return open (name, O_RDONLY); 314169695Skan} 315169695Skan 316169695Skan/* Open a file for writing. */ 317169695Skan 318169695Skanstatic int 319169695Skanpex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 320169695Skan int binary ATTRIBUTE_UNUSED) 321169695Skan{ 322169695Skan /* Note that we can't use O_EXCL here because gcc may have already 323169695Skan created the temporary file via make_temp_file. */ 324169695Skan return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE); 325169695Skan} 326169695Skan 327169695Skan/* Close a file. */ 328169695Skan 329169695Skanstatic int 330169695Skanpex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) 331169695Skan{ 332169695Skan return close (fd); 333169695Skan} 334169695Skan 335169695Skan/* Report an error from a child process. We don't use stdio routines, 336169695Skan because we might be here due to a vfork call. */ 337169695Skan 338169695Skanstatic void 339169695Skanpex_child_error (struct pex_obj *obj, const char *executable, 340169695Skan const char *errmsg, int err) 341169695Skan{ 342259705Spfg#define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s)) 343169695Skan writeerr (obj->pname); 344169695Skan writeerr (": error trying to exec '"); 345169695Skan writeerr (executable); 346169695Skan writeerr ("': "); 347169695Skan writeerr (errmsg); 348169695Skan writeerr (": "); 349169695Skan writeerr (xstrerror (err)); 350169695Skan writeerr ("\n"); 351169695Skan _exit (-1); 352169695Skan} 353169695Skan 354169695Skan/* Execute a child. */ 355169695Skan 356169695Skanextern char **environ; 357169695Skan 358169695Skanstatic long 359169695Skanpex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, 360169695Skan char * const * argv, char * const * env, 361169695Skan int in, int out, int errdes, 362169695Skan int toclose, const char **errmsg, int *err) 363169695Skan{ 364169695Skan pid_t pid; 365169695Skan 366169695Skan /* We declare these to be volatile to avoid warnings from gcc about 367169695Skan them being clobbered by vfork. */ 368169695Skan volatile int sleep_interval; 369169695Skan volatile int retries; 370169695Skan 371169695Skan sleep_interval = 1; 372169695Skan pid = -1; 373169695Skan for (retries = 0; retries < 4; ++retries) 374169695Skan { 375169695Skan pid = vfork (); 376169695Skan if (pid >= 0) 377169695Skan break; 378169695Skan sleep (sleep_interval); 379169695Skan sleep_interval *= 2; 380169695Skan } 381169695Skan 382169695Skan switch (pid) 383169695Skan { 384169695Skan case -1: 385169695Skan *err = errno; 386169695Skan *errmsg = VFORK_STRING; 387169695Skan return -1; 388169695Skan 389169695Skan case 0: 390169695Skan /* Child process. */ 391169695Skan if (in != STDIN_FILE_NO) 392169695Skan { 393169695Skan if (dup2 (in, STDIN_FILE_NO) < 0) 394169695Skan pex_child_error (obj, executable, "dup2", errno); 395169695Skan if (close (in) < 0) 396169695Skan pex_child_error (obj, executable, "close", errno); 397169695Skan } 398169695Skan if (out != STDOUT_FILE_NO) 399169695Skan { 400169695Skan if (dup2 (out, STDOUT_FILE_NO) < 0) 401169695Skan pex_child_error (obj, executable, "dup2", errno); 402169695Skan if (close (out) < 0) 403169695Skan pex_child_error (obj, executable, "close", errno); 404169695Skan } 405169695Skan if (errdes != STDERR_FILE_NO) 406169695Skan { 407169695Skan if (dup2 (errdes, STDERR_FILE_NO) < 0) 408169695Skan pex_child_error (obj, executable, "dup2", errno); 409169695Skan if (close (errdes) < 0) 410169695Skan pex_child_error (obj, executable, "close", errno); 411169695Skan } 412169695Skan if (toclose >= 0) 413169695Skan { 414169695Skan if (close (toclose) < 0) 415169695Skan pex_child_error (obj, executable, "close", errno); 416169695Skan } 417169695Skan if ((flags & PEX_STDERR_TO_STDOUT) != 0) 418169695Skan { 419169695Skan if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) 420169695Skan pex_child_error (obj, executable, "dup2", errno); 421169695Skan } 422169695Skan 423169695Skan if (env) 424169695Skan environ = (char**) env; 425169695Skan 426169695Skan if ((flags & PEX_SEARCH) != 0) 427169695Skan { 428169695Skan execvp (executable, argv); 429169695Skan pex_child_error (obj, executable, "execvp", errno); 430169695Skan } 431169695Skan else 432169695Skan { 433169695Skan execv (executable, argv); 434169695Skan pex_child_error (obj, executable, "execv", errno); 435169695Skan } 436169695Skan 437169695Skan /* NOTREACHED */ 438169695Skan return -1; 439169695Skan 440169695Skan default: 441169695Skan /* Parent process. */ 442169695Skan if (in != STDIN_FILE_NO) 443169695Skan { 444169695Skan if (close (in) < 0) 445169695Skan { 446169695Skan *err = errno; 447169695Skan *errmsg = "close"; 448169695Skan return -1; 449169695Skan } 450169695Skan } 451169695Skan if (out != STDOUT_FILE_NO) 452169695Skan { 453169695Skan if (close (out) < 0) 454169695Skan { 455169695Skan *err = errno; 456169695Skan *errmsg = "close"; 457169695Skan return -1; 458169695Skan } 459169695Skan } 460169695Skan if (errdes != STDERR_FILE_NO) 461169695Skan { 462169695Skan if (close (errdes) < 0) 463169695Skan { 464169695Skan *err = errno; 465169695Skan *errmsg = "close"; 466169695Skan return -1; 467169695Skan } 468169695Skan } 469169695Skan 470169695Skan return (long) pid; 471169695Skan } 472169695Skan} 473169695Skan 474169695Skan/* Wait for a child process to complete. */ 475169695Skan 476169695Skanstatic int 477169695Skanpex_unix_wait (struct pex_obj *obj, long pid, int *status, 478169695Skan struct pex_time *time, int done, const char **errmsg, 479169695Skan int *err) 480169695Skan{ 481169695Skan /* If we are cleaning up when the caller didn't retrieve process 482169695Skan status for some reason, encourage the process to go away. */ 483169695Skan if (done) 484169695Skan kill (pid, SIGTERM); 485169695Skan 486169695Skan if (pex_wait (obj, pid, status, time) < 0) 487169695Skan { 488169695Skan *err = errno; 489169695Skan *errmsg = "wait"; 490169695Skan return -1; 491169695Skan } 492169695Skan 493169695Skan return 0; 494169695Skan} 495169695Skan 496169695Skan/* Create a pipe. */ 497169695Skan 498169695Skanstatic int 499169695Skanpex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, 500169695Skan int binary ATTRIBUTE_UNUSED) 501169695Skan{ 502169695Skan return pipe (p); 503169695Skan} 504169695Skan 505169695Skan/* Get a FILE pointer to read from a file descriptor. */ 506169695Skan 507169695Skanstatic FILE * 508169695Skanpex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 509169695Skan int binary ATTRIBUTE_UNUSED) 510169695Skan{ 511169695Skan return fdopen (fd, "r"); 512169695Skan} 513169695Skan 514169695Skanstatic FILE * 515169695Skanpex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 516169695Skan int binary ATTRIBUTE_UNUSED) 517169695Skan{ 518169695Skan if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) 519169695Skan return NULL; 520169695Skan return fdopen (fd, "w"); 521169695Skan} 522169695Skan 523169695Skanstatic void 524169695Skanpex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) 525169695Skan{ 526169695Skan#if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) 527169695Skan while (obj->sysdep != NULL) 528169695Skan { 529169695Skan struct status_list *this; 530169695Skan struct status_list *next; 531169695Skan 532169695Skan this = (struct status_list *) obj->sysdep; 533169695Skan next = this->next; 534169695Skan free (this); 535169695Skan obj->sysdep = (void *) next; 536169695Skan } 537169695Skan#endif 538169695Skan} 539