Bump GDB's version number to 15.1.90.DATE-git.
[binutils-gdb.git] / libiberty / pex-unix.c
blobaf98062a94cd5829591432842b2736166c71d1f1
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.
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.
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.
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. */
22 #include "config.h"
23 #include "libiberty.h"
24 #include "pex-common.h"
25 #include "environ.h"
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
43 #include <sys/types.h>
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
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
79 typedef __char_ptr32 *__char_ptr_char_ptr32
80 __attribute__ ((mode (SI)));
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. */
85 static __char_ptr_char_ptr32
86 to_ptr32 (char **ptr64)
88 int argc;
89 __char_ptr_char_ptr32 short_argv;
91 /* Count number of arguments. */
92 for (argc = 0; ptr64[argc] != NULL; argc++)
95 /* Reallocate argv with 32 bit pointers. */
96 short_argv = (__char_ptr_char_ptr32) decc$malloc
97 (sizeof (__char_ptr32) * (argc + 1));
99 for (argc = 0; ptr64[argc] != NULL; argc++)
100 short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
102 short_argv[argc] = (__char_ptr32) 0;
103 return short_argv;
106 #else
107 #define to_ptr32(argv) argv
108 #endif
110 /* File mode to use for private and world-readable files. */
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
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. */
123 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
125 #ifdef HAVE_WAIT4
127 static pid_t
128 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
129 struct pex_time *time)
131 pid_t ret;
132 struct rusage r;
134 #ifdef HAVE_WAITPID
135 if (time == NULL)
136 return waitpid (pid, status, 0);
137 #endif
139 ret = wait4 (pid, status, 0, &r);
141 if (time != NULL)
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;
149 return ret;
152 #else /* ! defined (HAVE_WAIT4) */
154 #ifdef HAVE_WAITPID
156 #ifndef HAVE_GETRUSAGE
158 static pid_t
159 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
160 struct pex_time *time)
162 if (time != NULL)
163 memset (time, 0, sizeof (struct pex_time));
164 return waitpid (pid, status, 0);
167 #else /* defined (HAVE_GETRUSAGE) */
169 static pid_t
170 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
171 struct pex_time *time)
173 struct rusage r1, r2;
174 pid_t ret;
176 if (time == NULL)
177 return waitpid (pid, status, 0);
179 getrusage (RUSAGE_CHILDREN, &r1);
181 ret = waitpid (pid, status, 0);
182 if (ret < 0)
183 return ret;
185 getrusage (RUSAGE_CHILDREN, &r2);
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)
191 --time->user_seconds;
192 time->user_microseconds += 1000000;
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)
199 --time->system_seconds;
200 time->system_microseconds += 1000000;
203 return ret;
206 #endif /* defined (HAVE_GETRUSAGE) */
208 #else /* ! defined (HAVE_WAITPID) */
210 struct status_list
212 struct status_list *next;
213 pid_t pid;
214 int status;
215 struct pex_time time;
218 static pid_t
219 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
221 struct status_list **pp;
223 for (pp = (struct status_list **) &obj->sysdep;
224 *pp != NULL;
225 pp = &(*pp)->next)
227 if ((*pp)->pid == pid)
229 struct status_list *p;
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;
241 while (1)
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
250 if (time != NULL)
252 #ifdef HAVE_GETRUSAGE
253 getrusage (RUSAGE_CHILDREN, &r1);
254 #else
255 memset (&pt, 0, sizeof (struct pex_time));
256 #endif
259 cpid = wait (status);
261 #ifdef HAVE_GETRUSAGE
262 if (time != NULL && cpid >= 0)
264 getrusage (RUSAGE_CHILDREN, &r2);
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)
270 --pt.user_seconds;
271 pt.user_microseconds += 1000000;
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)
278 --pt.system_seconds;
279 pt.system_microseconds += 1000000;
282 #endif
284 if (cpid < 0 || cpid == pid)
286 if (time != NULL)
287 *time = pt;
288 return cpid;
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;
301 #endif /* ! defined (HAVE_WAITPID) */
302 #endif /* ! defined (HAVE_WAIT4) */
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 *);
318 /* The list of functions we pass to the common routines. */
320 const struct pex_funcs funcs =
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
333 /* Return a newly initialized pex_obj structure. */
335 struct pex_obj *
336 pex_init (int flags, const char *pname, const char *tempbase)
338 return pex_init_common (flags, pname, tempbase, &funcs);
341 /* Open a file for reading. */
343 static int
344 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
345 int binary ATTRIBUTE_UNUSED)
347 return open (name, O_RDONLY);
350 /* Open a file for writing. */
352 static int
353 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
354 int binary ATTRIBUTE_UNUSED, int append)
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);
362 /* Close a file. */
364 static int
365 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
367 return close (fd);
370 /* Execute a child. */
372 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
373 /* Implementation of pex->exec_child using the Cygwin spawn operation. */
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. */
380 static int
381 save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd)
383 int new_fd, flags;
385 flags = fcntl (old_fd, F_GETFD);
387 /* If we could not retrieve the flags, then OLD_FD was not open. */
388 if (flags < 0)
390 new_fd = -1, flags = 0;
391 if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0)
392 return -1;
394 /* If we wish to close OLD_FD, just mark it CLOEXEC. */
395 else if (child_fd == -1)
397 new_fd = old_fd;
398 if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0)
399 return -1;
401 /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD. */
402 else
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;
421 *pflags = flags;
422 if (pnew_fd)
423 *pnew_fd = new_fd;
424 else if (new_fd != old_fd)
425 abort ();
427 return 0;
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. */
433 static int
434 restore_fd(int old_fd, int save_fd, int flags)
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);
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)
445 if (flags & FD_CLOEXEC)
446 return 0;
447 return fcntl (old_fd, F_SETFD, flags);
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)
455 if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0)
456 return -1;
458 else
459 #endif
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;
466 return close (save_fd);
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)
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;
481 if (flags & PEX_STDERR_TO_STDOUT)
482 errdes = out;
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;
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);
517 /* If we were not given an environment, use the global environment. */
518 if (env == NULL)
519 env = environ;
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)
526 typedef const char * const *cc_cp;
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);
533 if (pid > 0)
534 break;
536 *err = errno;
537 *errmsg = "spawn";
538 if (errno != EAGAIN || ++retries == 4)
539 return (pid_t) -1;
540 sleep (1 << retries);
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;
557 return pid;
559 error_dup2:
560 *err = errno;
561 *errmsg = "dup2";
562 return (pid_t) -1;
565 #elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP)
566 /* Implementation of pex->exec_child using posix_spawn. */
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)
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;
581 *err = 0;
583 ret = posix_spawnattr_init (&attr);
584 if (ret)
586 *err = ret;
587 *errmsg = "posix_spawnattr_init";
588 goto exit;
590 attr_initialized = 1;
592 /* Use vfork() on glibc <=2.24. */
593 #ifdef POSIX_SPAWN_USEVFORK
594 ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK);
595 if (ret)
597 *err = ret;
598 *errmsg = "posix_spawnattr_setflags";
599 goto exit;
601 #endif
603 ret = posix_spawn_file_actions_init (&actions);
604 if (ret)
606 *err = ret;
607 *errmsg = "posix_spawn_file_actions_init";
608 goto exit;
610 actions_initialized = 1;
612 if (in != STDIN_FILE_NO)
614 ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO);
615 if (ret)
617 *err = ret;
618 *errmsg = "posix_spawn_file_actions_adddup2";
619 goto exit;
622 ret = posix_spawn_file_actions_addclose (&actions, in);
623 if (ret)
625 *err = ret;
626 *errmsg = "posix_spawn_file_actions_addclose";
627 goto exit;
631 if (out != STDOUT_FILE_NO)
633 ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO);
634 if (ret)
636 *err = ret;
637 *errmsg = "posix_spawn_file_actions_adddup2";
638 goto exit;
641 ret = posix_spawn_file_actions_addclose (&actions, out);
642 if (ret)
644 *err = ret;
645 *errmsg = "posix_spawn_file_actions_addclose";
646 goto exit;
650 if (errdes != STDERR_FILE_NO)
652 ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO);
653 if (ret)
655 *err = ret;
656 *errmsg = "posix_spawn_file_actions_adddup2";
657 goto exit;
660 ret = posix_spawn_file_actions_addclose (&actions, errdes);
661 if (ret)
663 *err = ret;
664 *errmsg = "posix_spawn_file_actions_addclose";
665 goto exit;
669 if (toclose >= 0)
671 ret = posix_spawn_file_actions_addclose (&actions, toclose);
672 if (ret)
674 *err = ret;
675 *errmsg = "posix_spawn_file_actions_addclose";
676 goto exit;
680 if ((flags & PEX_STDERR_TO_STDOUT) != 0)
682 ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO);
683 if (ret)
685 *err = ret;
686 *errmsg = "posix_spawn_file_actions_adddup2";
687 goto exit;
691 if ((flags & PEX_SEARCH) != 0)
693 ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ);
694 if (ret)
696 *err = ret;
697 *errmsg = "posix_spawnp";
698 goto exit;
701 else
703 ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ);
704 if (ret)
706 *err = ret;
707 *errmsg = "posix_spawn";
708 goto exit;
712 exit:
713 if (actions_initialized)
714 posix_spawn_file_actions_destroy (&actions);
715 if (attr_initialized)
716 posix_spawnattr_destroy (&attr);
718 if (!*err && in != STDIN_FILE_NO)
719 if (close (in))
720 *errmsg = "close", *err = errno, pid = -1;
721 if (!*err && out != STDOUT_FILE_NO)
722 if (close (out))
723 *errmsg = "close", *err = errno, pid = -1;
724 if (!*err && errdes != STDERR_FILE_NO)
725 if (close (errdes))
726 *errmsg = "close", *err = errno, pid = -1;
728 return pid;
730 #else
731 /* Implementation of pex->exec_child using standard vfork + exec. */
733 static pid_t
734 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
735 char * const * argv, char * const * env,
736 int in, int out, int errdes,
737 int toclose, const char **errmsg, int *err)
739 pid_t pid = -1;
740 /* Tuple to communicate error from child to parent. We can safely
741 transfer string literal pointers as both run with identical
742 address mappings. */
743 struct fn_err
745 const char *fn;
746 int err;
748 volatile int do_pipe = 0;
749 volatile int pipes[2]; /* [0]:reader,[1]:writer. */
750 #ifdef O_CLOEXEC
751 do_pipe = 1;
752 #endif
753 if (do_pipe)
755 #ifdef HAVE_PIPE2
756 if (pipe2 ((int *)pipes, O_CLOEXEC))
757 do_pipe = 0;
758 #else
759 if (pipe ((int *)pipes))
760 do_pipe = 0;
761 else
763 if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1)
765 close (pipes[0]);
766 close (pipes[1]);
767 do_pipe = 0;
770 #endif
773 /* We declare these to be volatile to avoid warnings from gcc about
774 them being clobbered by vfork. */
775 volatile int sleep_interval = 1;
776 volatile int retries;
778 /* We vfork and then set environ in the child before calling execvp.
779 This clobbers the parent's environ so we need to restore it.
780 It would be nice to use one of the exec* functions that takes an
781 environment as a parameter, but that may have portability
782 issues. It is marked volatile so the child doesn't consider it a
783 dead variable and therefore clobber where ever it is stored. */
784 char **volatile save_environ = environ;
786 for (retries = 0; retries < 4; ++retries)
788 pid = vfork ();
789 if (pid >= 0)
790 break;
791 sleep (sleep_interval);
792 sleep_interval *= 2;
795 switch (pid)
797 case -1:
798 if (do_pipe)
800 close (pipes[0]);
801 close (pipes[1]);
803 *err = errno;
804 *errmsg = VFORK_STRING;
805 return (pid_t) -1;
807 case 0:
808 /* Child process. */
810 struct fn_err failed;
811 failed.fn = NULL;
813 if (do_pipe)
814 close (pipes[0]);
815 if (!failed.fn && in != STDIN_FILE_NO)
817 if (dup2 (in, STDIN_FILE_NO) < 0)
818 failed.fn = "dup2", failed.err = errno;
819 else if (close (in) < 0)
820 failed.fn = "close", failed.err = errno;
822 if (!failed.fn && out != STDOUT_FILE_NO)
824 if (dup2 (out, STDOUT_FILE_NO) < 0)
825 failed.fn = "dup2", failed.err = errno;
826 else if (close (out) < 0)
827 failed.fn = "close", failed.err = errno;
829 if (!failed.fn && errdes != STDERR_FILE_NO)
831 if (dup2 (errdes, STDERR_FILE_NO) < 0)
832 failed.fn = "dup2", failed.err = errno;
833 else if (close (errdes) < 0)
834 failed.fn = "close", failed.err = errno;
836 if (!failed.fn && toclose >= 0)
838 if (close (toclose) < 0)
839 failed.fn = "close", failed.err = errno;
841 if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
843 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
844 failed.fn = "dup2", failed.err = errno;
846 if (!failed.fn)
848 if (env)
849 /* NOTE: In a standard vfork implementation this clobbers
850 the parent's copy of environ "too" (in reality there's
851 only one copy). This is ok as we restore it below. */
852 environ = (char**) env;
853 if ((flags & PEX_SEARCH) != 0)
855 execvp (executable, to_ptr32 (argv));
856 failed.fn = "execvp", failed.err = errno;
858 else
860 execv (executable, to_ptr32 (argv));
861 failed.fn = "execv", failed.err = errno;
865 /* Something failed, report an error. We don't use stdio
866 routines, because we might be here due to a vfork call. */
867 ssize_t retval = 0;
869 if (!do_pipe
870 || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed))
872 /* The parent will not see our scream above, so write to
873 stdout. */
874 #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
875 writeerr (obj->pname);
876 writeerr (": error trying to exec '");
877 writeerr (executable);
878 writeerr ("': ");
879 writeerr (failed.fn);
880 writeerr (": ");
881 writeerr (xstrerror (failed.err));
882 writeerr ("\n");
883 #undef writeerr
886 /* Exit with -2 if the error output failed, too. */
887 _exit (retval < 0 ? -2 : -1);
889 /* NOTREACHED */
890 return (pid_t) -1;
892 default:
893 /* Parent process. */
895 /* Restore environ. Note that the parent either doesn't run
896 until the child execs/exits (standard vfork behaviour), or
897 if it does run then vfork is behaving more like fork. In
898 either case we needn't worry about clobbering the child's
899 copy of environ. */
900 environ = save_environ;
902 struct fn_err failed;
903 failed.fn = NULL;
904 if (do_pipe)
906 close (pipes[1]);
907 ssize_t len = read (pipes[0], &failed, sizeof (failed));
908 if (len < 0)
909 failed.fn = NULL;
910 close (pipes[0]);
913 if (!failed.fn && in != STDIN_FILE_NO)
914 if (close (in) < 0)
915 failed.fn = "close", failed.err = errno;
916 if (!failed.fn && out != STDOUT_FILE_NO)
917 if (close (out) < 0)
918 failed.fn = "close", failed.err = errno;
919 if (!failed.fn && errdes != STDERR_FILE_NO)
920 if (close (errdes) < 0)
921 failed.fn = "close", failed.err = errno;
923 if (failed.fn)
925 *err = failed.err;
926 *errmsg = failed.fn;
927 return (pid_t) -1;
930 return pid;
933 #endif /* SPAWN */
935 /* Wait for a child process to complete. */
937 static pid_t
938 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
939 struct pex_time *time, int done, const char **errmsg,
940 int *err)
942 /* If we are cleaning up when the caller didn't retrieve process
943 status for some reason, encourage the process to go away. */
944 if (done)
945 kill (pid, SIGTERM);
947 if (pex_wait (obj, pid, status, time) < 0)
949 *err = errno;
950 *errmsg = "wait";
951 return -1;
954 return 0;
957 /* Create a pipe. */
959 static int
960 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
961 int binary ATTRIBUTE_UNUSED)
963 return pipe (p);
966 /* Get a FILE pointer to read from a file descriptor. */
968 static FILE *
969 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
970 int binary ATTRIBUTE_UNUSED)
972 return fdopen (fd, "r");
975 static FILE *
976 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
977 int binary ATTRIBUTE_UNUSED)
979 if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
980 return NULL;
981 return fdopen (fd, "w");
984 static void
985 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
987 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
988 while (obj->sysdep != NULL)
990 struct status_list *this;
991 struct status_list *next;
993 this = (struct status_list *) obj->sysdep;
994 next = this->next;
995 free (this);
996 obj->sysdep = (void *) next;
998 #endif