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-2024 Free Software Foundation, Inc. 5 6 This file is part of the libiberty library. 7 Libiberty is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Library General Public 9 License as published by the Free Software Foundation; either 10 version 2 of the License, or (at your option) any later version. 11 12 Libiberty is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public 18 License along with libiberty; see the file COPYING.LIB. If not, 19 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 20 Boston, MA 02110-1301, USA. */ 21 22 #include "config.h" 23 #include "libiberty.h" 24 #include "pex-common.h" 25 #include "environ.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 #ifdef HAVE_PROCESS_H 59 #include <process.h> 60 #endif 61 #ifdef HAVE_SPAWN_H 62 #include <spawn.h> 63 #endif 64 65 #ifdef vfork /* Autoconf may define this to fork for us. */ 66 # define VFORK_STRING "fork" 67 #else 68 # define VFORK_STRING "vfork" 69 #endif 70 #ifdef HAVE_VFORK_H 71 #include <vfork.h> 72 #endif 73 #if defined(VMS) && defined (__LONG_POINTERS) 74 #ifndef __CHAR_PTR32 75 typedef char * __char_ptr32 76 __attribute__ ((mode (SI))); 77 #endif 78 79 typedef __char_ptr32 *__char_ptr_char_ptr32 80 __attribute__ ((mode (SI))); 81 82 /* Return a 32 bit pointer to an array of 32 bit pointers 83 given a 64 bit pointer to an array of 64 bit pointers. */ 84 85 static __char_ptr_char_ptr32 86 to_ptr32 (char **ptr64) 87 { 88 int argc; 89 __char_ptr_char_ptr32 short_argv; 90 91 /* Count number of arguments. */ 92 for (argc = 0; ptr64[argc] != NULL; argc++) 93 ; 94 95 /* Reallocate argv with 32 bit pointers. */ 96 short_argv = (__char_ptr_char_ptr32) decc$malloc 97 (sizeof (__char_ptr32) * (argc + 1)); 98 99 for (argc = 0; ptr64[argc] != NULL; argc++) 100 short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]); 101 102 short_argv[argc] = (__char_ptr32) 0; 103 return short_argv; 104 105 } 106 #else 107 #define to_ptr32(argv) argv 108 #endif 109 110 /* File mode to use for private and world-readable files. */ 111 112 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) 113 #define PUBLIC_MODE \ 114 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 115 #else 116 #define PUBLIC_MODE 0666 117 #endif 118 119 /* Get the exit status of a particular process, and optionally get the 120 time that it took. This is simple if we have wait4, slightly 121 harder if we have waitpid, and is a pain if we only have wait. */ 122 123 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); 124 125 #ifdef HAVE_WAIT4 126 127 static pid_t 128 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 129 struct pex_time *time) 130 { 131 pid_t ret; 132 struct rusage r; 133 134 #ifdef HAVE_WAITPID 135 if (time == NULL) 136 return waitpid (pid, status, 0); 137 #endif 138 139 ret = wait4 (pid, status, 0, &r); 140 141 if (time != NULL) 142 { 143 time->user_seconds = r.ru_utime.tv_sec; 144 time->user_microseconds= r.ru_utime.tv_usec; 145 time->system_seconds = r.ru_stime.tv_sec; 146 time->system_microseconds= r.ru_stime.tv_usec; 147 } 148 149 return ret; 150 } 151 152 #else /* ! defined (HAVE_WAIT4) */ 153 154 #ifdef HAVE_WAITPID 155 156 #ifndef HAVE_GETRUSAGE 157 158 static pid_t 159 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 160 struct pex_time *time) 161 { 162 if (time != NULL) 163 memset (time, 0, sizeof (struct pex_time)); 164 return waitpid (pid, status, 0); 165 } 166 167 #else /* defined (HAVE_GETRUSAGE) */ 168 169 static pid_t 170 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, 171 struct pex_time *time) 172 { 173 struct rusage r1, r2; 174 pid_t ret; 175 176 if (time == NULL) 177 return waitpid (pid, status, 0); 178 179 getrusage (RUSAGE_CHILDREN, &r1); 180 181 ret = waitpid (pid, status, 0); 182 if (ret < 0) 183 return ret; 184 185 getrusage (RUSAGE_CHILDREN, &r2); 186 187 time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 188 time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 189 if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) 190 { 191 --time->user_seconds; 192 time->user_microseconds += 1000000; 193 } 194 195 time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 196 time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 197 if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) 198 { 199 --time->system_seconds; 200 time->system_microseconds += 1000000; 201 } 202 203 return ret; 204 } 205 206 #endif /* defined (HAVE_GETRUSAGE) */ 207 208 #else /* ! defined (HAVE_WAITPID) */ 209 210 struct status_list 211 { 212 struct status_list *next; 213 pid_t pid; 214 int status; 215 struct pex_time time; 216 }; 217 218 static pid_t 219 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) 220 { 221 struct status_list **pp; 222 223 for (pp = (struct status_list **) &obj->sysdep; 224 *pp != NULL; 225 pp = &(*pp)->next) 226 { 227 if ((*pp)->pid == pid) 228 { 229 struct status_list *p; 230 231 p = *pp; 232 *status = p->status; 233 if (time != NULL) 234 *time = p->time; 235 *pp = p->next; 236 free (p); 237 return pid; 238 } 239 } 240 241 while (1) 242 { 243 pid_t cpid; 244 struct status_list *psl; 245 struct pex_time pt; 246 #ifdef HAVE_GETRUSAGE 247 struct rusage r1, r2; 248 #endif 249 250 if (time != NULL) 251 { 252 #ifdef HAVE_GETRUSAGE 253 getrusage (RUSAGE_CHILDREN, &r1); 254 #else 255 memset (&pt, 0, sizeof (struct pex_time)); 256 #endif 257 } 258 259 cpid = wait (status); 260 261 #ifdef HAVE_GETRUSAGE 262 if (time != NULL && cpid >= 0) 263 { 264 getrusage (RUSAGE_CHILDREN, &r2); 265 266 pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; 267 pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; 268 if (pt.user_microseconds < 0) 269 { 270 --pt.user_seconds; 271 pt.user_microseconds += 1000000; 272 } 273 274 pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; 275 pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; 276 if (pt.system_microseconds < 0) 277 { 278 --pt.system_seconds; 279 pt.system_microseconds += 1000000; 280 } 281 } 282 #endif 283 284 if (cpid < 0 || cpid == pid) 285 { 286 if (time != NULL) 287 *time = pt; 288 return cpid; 289 } 290 291 psl = XNEW (struct status_list); 292 psl->pid = cpid; 293 psl->status = *status; 294 if (time != NULL) 295 psl->time = pt; 296 psl->next = (struct status_list *) obj->sysdep; 297 obj->sysdep = (void *) psl; 298 } 299 } 300 301 #endif /* ! defined (HAVE_WAITPID) */ 302 #endif /* ! defined (HAVE_WAIT4) */ 303 304 static int pex_unix_open_read (struct pex_obj *, const char *, int); 305 static int pex_unix_open_write (struct pex_obj *, const char *, int, int); 306 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *, 307 char * const *, char * const *, 308 int, int, int, int, 309 const char **, int *); 310 static int pex_unix_close (struct pex_obj *, int); 311 static pid_t pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, 312 int, const char **, int *); 313 static int pex_unix_pipe (struct pex_obj *, int *, int); 314 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); 315 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); 316 static void pex_unix_cleanup (struct pex_obj *); 317 318 /* The list of functions we pass to the common routines. */ 319 320 const struct pex_funcs funcs = 321 { 322 pex_unix_open_read, 323 pex_unix_open_write, 324 pex_unix_exec_child, 325 pex_unix_close, 326 pex_unix_wait, 327 pex_unix_pipe, 328 pex_unix_fdopenr, 329 pex_unix_fdopenw, 330 pex_unix_cleanup 331 }; 332 333 /* Return a newly initialized pex_obj structure. */ 334 335 struct pex_obj * 336 pex_init (int flags, const char *pname, const char *tempbase) 337 { 338 return pex_init_common (flags, pname, tempbase, &funcs); 339 } 340 341 /* Open a file for reading. */ 342 343 static int 344 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 345 int binary ATTRIBUTE_UNUSED) 346 { 347 return open (name, O_RDONLY); 348 } 349 350 /* Open a file for writing. */ 351 352 static int 353 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, 354 int binary ATTRIBUTE_UNUSED, int append) 355 { 356 /* Note that we can't use O_EXCL here because gcc may have already 357 created the temporary file via make_temp_file. */ 358 return open (name, O_WRONLY | O_CREAT 359 | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE); 360 } 361 362 /* Close a file. */ 363 364 static int 365 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) 366 { 367 return close (fd); 368 } 369 370 /* Execute a child. */ 371 372 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE) 373 /* Implementation of pex->exec_child using the Cygwin spawn operation. */ 374 375 /* Subroutine of pex_unix_exec_child. Move OLD_FD to a new file descriptor 376 to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the 377 saved copy to be close-on-exec. Move CHILD_FD into OLD_FD. If CHILD_FD 378 is -1, OLD_FD is to be closed. Return -1 on error. */ 379 380 static int 381 save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd) 382 { 383 int new_fd, flags; 384 385 flags = fcntl (old_fd, F_GETFD); 386 387 /* If we could not retrieve the flags, then OLD_FD was not open. */ 388 if (flags < 0) 389 { 390 new_fd = -1, flags = 0; 391 if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0) 392 return -1; 393 } 394 /* If we wish to close OLD_FD, just mark it CLOEXEC. */ 395 else if (child_fd == -1) 396 { 397 new_fd = old_fd; 398 if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0) 399 return -1; 400 } 401 /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD. */ 402 else 403 { 404 #ifdef F_DUPFD_CLOEXEC 405 new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3); 406 if (new_fd < 0) 407 return -1; 408 #else 409 /* Prefer F_DUPFD over dup in order to avoid getting a new fd 410 in the range 0-2, right where a new stderr fd might get put. */ 411 new_fd = fcntl (old_fd, F_DUPFD, 3); 412 if (new_fd < 0) 413 return -1; 414 if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0) 415 return -1; 416 #endif 417 if (dup2 (child_fd, old_fd) < 0) 418 return -1; 419 } 420 421 *pflags = flags; 422 if (pnew_fd) 423 *pnew_fd = new_fd; 424 else if (new_fd != old_fd) 425 abort (); 426 427 return 0; 428 } 429 430 /* Subroutine of pex_unix_exec_child. Move SAVE_FD back to OLD_FD 431 restoring FLAGS. If SAVE_FD < 0, OLD_FD is to be closed. */ 432 433 static int 434 restore_fd(int old_fd, int save_fd, int flags) 435 { 436 /* For SAVE_FD < 0, all we have to do is restore the 437 "closed-ness" of the original. */ 438 if (save_fd < 0) 439 return close (old_fd); 440 441 /* For SAVE_FD == OLD_FD, all we have to do is restore the 442 original setting of the CLOEXEC flag. */ 443 if (save_fd == old_fd) 444 { 445 if (flags & FD_CLOEXEC) 446 return 0; 447 return fcntl (old_fd, F_SETFD, flags); 448 } 449 450 /* Otherwise we have to move the descriptor back, restore the flags, 451 and close the saved copy. */ 452 #ifdef HAVE_DUP3 453 if (flags == FD_CLOEXEC) 454 { 455 if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0) 456 return -1; 457 } 458 else 459 #endif 460 { 461 if (dup2 (save_fd, old_fd) < 0) 462 return -1; 463 if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0) 464 return -1; 465 } 466 return close (save_fd); 467 } 468 469 static pid_t 470 pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, 471 int flags, const char *executable, 472 char * const * argv, char * const * env, 473 int in, int out, int errdes, int toclose, 474 const char **errmsg, int *err) 475 { 476 int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0; 477 int save_in = -1, save_out = -1, save_err = -1; 478 int max, retries; 479 pid_t pid; 480 481 if (flags & PEX_STDERR_TO_STDOUT) 482 errdes = out; 483 484 /* We need the three standard file descriptors to be set up as for 485 the child before we perform the spawn. The file descriptors for 486 the parent need to be moved and marked for close-on-exec. */ 487 if (in != STDIN_FILE_NO 488 && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0) 489 goto error_dup2; 490 if (out != STDOUT_FILE_NO 491 && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0) 492 goto error_dup2; 493 if (errdes != STDERR_FILE_NO 494 && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0) 495 goto error_dup2; 496 if (toclose >= 0 497 && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0) 498 goto error_dup2; 499 500 /* Now that we've moved the file descriptors for the child into place, 501 close the originals. Be careful not to close any of the standard 502 file descriptors that we just set up. */ 503 max = -1; 504 if (errdes >= 0) 505 max = STDERR_FILE_NO; 506 else if (out >= 0) 507 max = STDOUT_FILE_NO; 508 else if (in >= 0) 509 max = STDIN_FILE_NO; 510 if (in > max) 511 close (in); 512 if (out > max) 513 close (out); 514 if (errdes > max && errdes != out) 515 close (errdes); 516 517 /* If we were not given an environment, use the global environment. */ 518 if (env == NULL) 519 env = environ; 520 521 /* Launch the program. If we get EAGAIN (normally out of pid's), try 522 again a few times with increasing backoff times. */ 523 retries = 0; 524 while (1) 525 { 526 typedef const char * const *cc_cp; 527 528 if (flags & PEX_SEARCH) 529 pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); 530 else 531 pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); 532 533 if (pid > 0) 534 break; 535 536 *err = errno; 537 *errmsg = "spawn"; 538 if (errno != EAGAIN || ++retries == 4) 539 return (pid_t) -1; 540 sleep (1 << retries); 541 } 542 543 /* Success. Restore the parent's file descriptors that we saved above. */ 544 if (toclose >= 0 545 && restore_fd (toclose, toclose, fl_tc) < 0) 546 goto error_dup2; 547 if (in != STDIN_FILE_NO 548 && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0) 549 goto error_dup2; 550 if (out != STDOUT_FILE_NO 551 && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0) 552 goto error_dup2; 553 if (errdes != STDERR_FILE_NO 554 && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0) 555 goto error_dup2; 556 557 return pid; 558 559 error_dup2: 560 *err = errno; 561 *errmsg = "dup2"; 562 return (pid_t) -1; 563 } 564 565 #elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP) 566 /* Implementation of pex->exec_child using posix_spawn. */ 567 568 static pid_t 569 pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, 570 int flags, const char *executable, 571 char * const * argv, char * const * env, 572 int in, int out, int errdes, 573 int toclose, const char **errmsg, int *err) 574 { 575 int ret; 576 pid_t pid = -1; 577 posix_spawnattr_t attr; 578 posix_spawn_file_actions_t actions; 579 int attr_initialized = 0, actions_initialized = 0; 580 581 *err = 0; 582 583 ret = posix_spawnattr_init (&attr); 584 if (ret) 585 { 586 *err = ret; 587 *errmsg = "posix_spawnattr_init"; 588 goto exit; 589 } 590 attr_initialized = 1; 591 592 /* Use vfork() on glibc <=2.24. */ 593 #ifdef POSIX_SPAWN_USEVFORK 594 ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK); 595 if (ret) 596 { 597 *err = ret; 598 *errmsg = "posix_spawnattr_setflags"; 599 goto exit; 600 } 601 #endif 602 603 ret = posix_spawn_file_actions_init (&actions); 604 if (ret) 605 { 606 *err = ret; 607 *errmsg = "posix_spawn_file_actions_init"; 608 goto exit; 609 } 610 actions_initialized = 1; 611 612 if (in != STDIN_FILE_NO) 613 { 614 ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO); 615 if (ret) 616 { 617 *err = ret; 618 *errmsg = "posix_spawn_file_actions_adddup2"; 619 goto exit; 620 } 621 622 ret = posix_spawn_file_actions_addclose (&actions, in); 623 if (ret) 624 { 625 *err = ret; 626 *errmsg = "posix_spawn_file_actions_addclose"; 627 goto exit; 628 } 629 } 630 631 if (out != STDOUT_FILE_NO) 632 { 633 ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO); 634 if (ret) 635 { 636 *err = ret; 637 *errmsg = "posix_spawn_file_actions_adddup2"; 638 goto exit; 639 } 640 641 ret = posix_spawn_file_actions_addclose (&actions, out); 642 if (ret) 643 { 644 *err = ret; 645 *errmsg = "posix_spawn_file_actions_addclose"; 646 goto exit; 647 } 648 } 649 650 if (errdes != STDERR_FILE_NO) 651 { 652 ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO); 653 if (ret) 654 { 655 *err = ret; 656 *errmsg = "posix_spawn_file_actions_adddup2"; 657 goto exit; 658 } 659 660 ret = posix_spawn_file_actions_addclose (&actions, errdes); 661 if (ret) 662 { 663 *err = ret; 664 *errmsg = "posix_spawn_file_actions_addclose"; 665 goto exit; 666 } 667 } 668 669 if (toclose >= 0) 670 { 671 ret = posix_spawn_file_actions_addclose (&actions, toclose); 672 if (ret) 673 { 674 *err = ret; 675 *errmsg = "posix_spawn_file_actions_addclose"; 676 goto exit; 677 } 678 } 679 680 if ((flags & PEX_STDERR_TO_STDOUT) != 0) 681 { 682 ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO); 683 if (ret) 684 { 685 *err = ret; 686 *errmsg = "posix_spawn_file_actions_adddup2"; 687 goto exit; 688 } 689 } 690 691 if ((flags & PEX_SEARCH) != 0) 692 { 693 ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ); 694 if (ret) 695 { 696 *err = ret; 697 *errmsg = "posix_spawnp"; 698 pid = -1; /* The value of pid is unspecified on failure. */ 699 goto exit; 700 } 701 } 702 else 703 { 704 ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ); 705 if (ret) 706 { 707 *err = ret; 708 *errmsg = "posix_spawn"; 709 pid = -1; 710 goto exit; 711 } 712 } 713 714 exit: 715 if (actions_initialized) 716 posix_spawn_file_actions_destroy (&actions); 717 if (attr_initialized) 718 posix_spawnattr_destroy (&attr); 719 720 if (!*err && in != STDIN_FILE_NO) 721 if (close (in)) 722 *errmsg = "close", *err = errno, pid = -1; 723 if (!*err && out != STDOUT_FILE_NO) 724 if (close (out)) 725 *errmsg = "close", *err = errno, pid = -1; 726 if (!*err && errdes != STDERR_FILE_NO) 727 if (close (errdes)) 728 *errmsg = "close", *err = errno, pid = -1; 729 730 return pid; 731 } 732 #else 733 /* Implementation of pex->exec_child using standard vfork + exec. */ 734 735 static pid_t 736 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, 737 char * const * argv, char * const * env, 738 int in, int out, int errdes, 739 int toclose, const char **errmsg, int *err) 740 { 741 pid_t pid = -1; 742 /* Tuple to communicate error from child to parent. We can safely 743 transfer string literal pointers as both run with identical 744 address mappings. */ 745 struct fn_err 746 { 747 const char *fn; 748 int err; 749 }; 750 volatile int do_pipe = 0; 751 volatile int pipes[2]; /* [0]:reader,[1]:writer. */ 752 #ifdef O_CLOEXEC 753 do_pipe = 1; 754 #endif 755 if (do_pipe) 756 { 757 #ifdef HAVE_PIPE2 758 if (pipe2 ((int *)pipes, O_CLOEXEC)) 759 do_pipe = 0; 760 #else 761 if (pipe ((int *)pipes)) 762 do_pipe = 0; 763 else 764 { 765 if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1) 766 { 767 close (pipes[0]); 768 close (pipes[1]); 769 do_pipe = 0; 770 } 771 } 772 #endif 773 } 774 775 /* We declare these to be volatile to avoid warnings from gcc about 776 them being clobbered by vfork. */ 777 volatile int sleep_interval = 1; 778 volatile int retries; 779 780 /* We vfork and then set environ in the child before calling execvp. 781 This clobbers the parent's environ so we need to restore it. 782 It would be nice to use one of the exec* functions that takes an 783 environment as a parameter, but that may have portability 784 issues. It is marked volatile so the child doesn't consider it a 785 dead variable and therefore clobber where ever it is stored. */ 786 char **volatile save_environ = environ; 787 788 for (retries = 0; retries < 4; ++retries) 789 { 790 pid = vfork (); 791 if (pid >= 0) 792 break; 793 sleep (sleep_interval); 794 sleep_interval *= 2; 795 } 796 797 switch (pid) 798 { 799 case -1: 800 if (do_pipe) 801 { 802 close (pipes[0]); 803 close (pipes[1]); 804 } 805 *err = errno; 806 *errmsg = VFORK_STRING; 807 return (pid_t) -1; 808 809 case 0: 810 /* Child process. */ 811 { 812 struct fn_err failed; 813 failed.fn = NULL; 814 815 if (do_pipe) 816 close (pipes[0]); 817 if (!failed.fn && in != STDIN_FILE_NO) 818 { 819 if (dup2 (in, STDIN_FILE_NO) < 0) 820 failed.fn = "dup2", failed.err = errno; 821 else if (close (in) < 0) 822 failed.fn = "close", failed.err = errno; 823 } 824 if (!failed.fn && out != STDOUT_FILE_NO) 825 { 826 if (dup2 (out, STDOUT_FILE_NO) < 0) 827 failed.fn = "dup2", failed.err = errno; 828 else if (close (out) < 0) 829 failed.fn = "close", failed.err = errno; 830 } 831 if (!failed.fn && errdes != STDERR_FILE_NO) 832 { 833 if (dup2 (errdes, STDERR_FILE_NO) < 0) 834 failed.fn = "dup2", failed.err = errno; 835 else if (close (errdes) < 0) 836 failed.fn = "close", failed.err = errno; 837 } 838 if (!failed.fn && toclose >= 0) 839 { 840 if (close (toclose) < 0) 841 failed.fn = "close", failed.err = errno; 842 } 843 if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0) 844 { 845 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) 846 failed.fn = "dup2", failed.err = errno; 847 } 848 if (!failed.fn) 849 { 850 if (env) 851 /* NOTE: In a standard vfork implementation this clobbers 852 the parent's copy of environ "too" (in reality there's 853 only one copy). This is ok as we restore it below. */ 854 environ = (char**) env; 855 if ((flags & PEX_SEARCH) != 0) 856 { 857 execvp (executable, to_ptr32 (argv)); 858 failed.fn = "execvp", failed.err = errno; 859 } 860 else 861 { 862 execv (executable, to_ptr32 (argv)); 863 failed.fn = "execv", failed.err = errno; 864 } 865 } 866 867 /* Something failed, report an error. We don't use stdio 868 routines, because we might be here due to a vfork call. */ 869 ssize_t retval = 0; 870 871 if (!do_pipe 872 || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed)) 873 { 874 /* The parent will not see our scream above, so write to 875 stdout. */ 876 #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s))) 877 writeerr (obj->pname); 878 writeerr (": error trying to exec '"); 879 writeerr (executable); 880 writeerr ("': "); 881 writeerr (failed.fn); 882 writeerr (": "); 883 writeerr (xstrerror (failed.err)); 884 writeerr ("\n"); 885 #undef writeerr 886 } 887 888 /* Exit with -2 if the error output failed, too. */ 889 _exit (retval < 0 ? -2 : -1); 890 } 891 /* NOTREACHED */ 892 return (pid_t) -1; 893 894 default: 895 /* Parent process. */ 896 { 897 /* Restore environ. Note that the parent either doesn't run 898 until the child execs/exits (standard vfork behaviour), or 899 if it does run then vfork is behaving more like fork. In 900 either case we needn't worry about clobbering the child's 901 copy of environ. */ 902 environ = save_environ; 903 904 struct fn_err failed; 905 failed.fn = NULL; 906 if (do_pipe) 907 { 908 close (pipes[1]); 909 ssize_t len = read (pipes[0], &failed, sizeof (failed)); 910 if (len < 0) 911 failed.fn = NULL; 912 close (pipes[0]); 913 } 914 915 if (!failed.fn && in != STDIN_FILE_NO) 916 if (close (in) < 0) 917 failed.fn = "close", failed.err = errno; 918 if (!failed.fn && out != STDOUT_FILE_NO) 919 if (close (out) < 0) 920 failed.fn = "close", failed.err = errno; 921 if (!failed.fn && errdes != STDERR_FILE_NO) 922 if (close (errdes) < 0) 923 failed.fn = "close", failed.err = errno; 924 925 if (failed.fn) 926 { 927 *err = failed.err; 928 *errmsg = failed.fn; 929 return (pid_t) -1; 930 } 931 } 932 return pid; 933 } 934 } 935 #endif /* SPAWN */ 936 937 /* Wait for a child process to complete. */ 938 939 static pid_t 940 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status, 941 struct pex_time *time, int done, const char **errmsg, 942 int *err) 943 { 944 /* If we are cleaning up when the caller didn't retrieve process 945 status for some reason, encourage the process to go away. */ 946 if (done) 947 kill (pid, SIGTERM); 948 949 if (pex_wait (obj, pid, status, time) < 0) 950 { 951 *err = errno; 952 *errmsg = "wait"; 953 return -1; 954 } 955 956 return 0; 957 } 958 959 /* Create a pipe. */ 960 961 static int 962 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, 963 int binary ATTRIBUTE_UNUSED) 964 { 965 return pipe (p); 966 } 967 968 /* Get a FILE pointer to read from a file descriptor. */ 969 970 static FILE * 971 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 972 int binary ATTRIBUTE_UNUSED) 973 { 974 return fdopen (fd, "r"); 975 } 976 977 static FILE * 978 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, 979 int binary ATTRIBUTE_UNUSED) 980 { 981 if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) 982 return NULL; 983 return fdopen (fd, "w"); 984 } 985 986 static void 987 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) 988 { 989 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) 990 while (obj->sysdep != NULL) 991 { 992 struct status_list *this; 993 struct status_list *next; 994 995 this = (struct status_list *) obj->sysdep; 996 next = this->next; 997 free (this); 998 obj->sysdep = (void *) next; 999 } 1000 #endif 1001 } 1002