xref: /netbsd-src/external/gpl3/binutils/dist/libiberty/pex-unix.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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
to_ptr32(char ** ptr64)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
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)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
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)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
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)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
pex_wait(struct pex_obj * obj,pid_t pid,int * status,struct pex_time * time)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 *
pex_init(int flags,const char * pname,const char * tempbase)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
pex_unix_open_read(struct pex_obj * obj ATTRIBUTE_UNUSED,const char * name,int binary ATTRIBUTE_UNUSED)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
pex_unix_open_write(struct pex_obj * obj ATTRIBUTE_UNUSED,const char * name,int binary ATTRIBUTE_UNUSED,int append)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
pex_unix_close(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd)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
save_and_install_fd(int * pnew_fd,int * pflags,int old_fd,int child_fd)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
restore_fd(int old_fd,int save_fd,int flags)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
pex_unix_exec_child(struct pex_obj * obj ATTRIBUTE_UNUSED,int flags,const char * executable,char * const * argv,char * const * env,int in,int out,int errdes,int toclose,const char ** errmsg,int * err)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
pex_unix_exec_child(struct pex_obj * obj ATTRIBUTE_UNUSED,int flags,const char * executable,char * const * argv,char * const * env,int in,int out,int errdes,int toclose,const char ** errmsg,int * err)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 	  goto exit;
699 	}
700     }
701   else
702     {
703       ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ);
704       if (ret)
705 	{
706 	  *err = ret;
707 	  *errmsg = "posix_spawn";
708 	  goto exit;
709 	}
710     }
711 
712 exit:
713   if (actions_initialized)
714     posix_spawn_file_actions_destroy (&actions);
715   if (attr_initialized)
716     posix_spawnattr_destroy (&attr);
717 
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;
727 
728   return pid;
729 }
730 #else
731 /* Implementation of pex->exec_child using standard vfork + exec.  */
732 
733 static pid_t
pex_unix_exec_child(struct pex_obj * obj,int flags,const char * executable,char * const * argv,char * const * env,int in,int out,int errdes,int toclose,const char ** errmsg,int * err)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)
738 {
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
744   {
745     const char *fn;
746     int err;
747   };
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)
754     {
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
762 	{
763 	  if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1)
764 	    {
765 	      close (pipes[0]);
766 	      close (pipes[1]);
767 	      do_pipe = 0;
768 	    }
769 	}
770 #endif
771     }
772 
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;
777 
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;
785 
786   for (retries = 0; retries < 4; ++retries)
787     {
788       pid = vfork ();
789       if (pid >= 0)
790 	break;
791       sleep (sleep_interval);
792       sleep_interval *= 2;
793     }
794 
795   switch (pid)
796     {
797     case -1:
798       if (do_pipe)
799 	{
800 	  close (pipes[0]);
801 	  close (pipes[1]);
802 	}
803       *err = errno;
804       *errmsg = VFORK_STRING;
805       return (pid_t) -1;
806 
807     case 0:
808       /* Child process.  */
809       {
810 	struct fn_err failed;
811 	failed.fn = NULL;
812 
813 	if (do_pipe)
814 	  close (pipes[0]);
815 	if (!failed.fn && in != STDIN_FILE_NO)
816 	  {
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;
821 	  }
822 	if (!failed.fn && out != STDOUT_FILE_NO)
823 	  {
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;
828 	  }
829 	if (!failed.fn && errdes != STDERR_FILE_NO)
830 	  {
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;
835 	  }
836 	if (!failed.fn && toclose >= 0)
837 	  {
838 	    if (close (toclose) < 0)
839 	      failed.fn = "close", failed.err = errno;
840 	  }
841 	if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
842 	  {
843 	    if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
844 	      failed.fn = "dup2", failed.err = errno;
845 	  }
846 	if (!failed.fn)
847 	  {
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)
854 	      {
855 		execvp (executable, to_ptr32 (argv));
856 		failed.fn = "execvp", failed.err = errno;
857 	      }
858 	    else
859 	      {
860 		execv (executable, to_ptr32 (argv));
861 		failed.fn = "execv", failed.err = errno;
862 	      }
863 	  }
864 
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;
868 
869 	if (!do_pipe
870 	    || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed))
871 	  {
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
884 	  }
885 
886 	/* Exit with -2 if the error output failed, too.  */
887 	_exit (retval < 0 ? -2 : -1);
888       }
889       /* NOTREACHED */
890       return (pid_t) -1;
891 
892     default:
893       /* Parent process.  */
894       {
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;
901 
902 	struct fn_err failed;
903 	failed.fn = NULL;
904 	if (do_pipe)
905 	  {
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]);
911 	  }
912 
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;
922 
923 	if (failed.fn)
924 	  {
925 	    *err = failed.err;
926 	    *errmsg = failed.fn;
927 	    return (pid_t) -1;
928 	  }
929       }
930       return pid;
931     }
932 }
933 #endif /* SPAWN */
934 
935 /* Wait for a child process to complete.  */
936 
937 static pid_t
pex_unix_wait(struct pex_obj * obj,pid_t pid,int * status,struct pex_time * time,int done,const char ** errmsg,int * err)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)
941 {
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);
946 
947   if (pex_wait (obj, pid, status, time) < 0)
948     {
949       *err = errno;
950       *errmsg = "wait";
951       return -1;
952     }
953 
954   return 0;
955 }
956 
957 /* Create a pipe.  */
958 
959 static int
pex_unix_pipe(struct pex_obj * obj ATTRIBUTE_UNUSED,int * p,int binary ATTRIBUTE_UNUSED)960 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
961 	       int binary ATTRIBUTE_UNUSED)
962 {
963   return pipe (p);
964 }
965 
966 /* Get a FILE pointer to read from a file descriptor.  */
967 
968 static FILE *
pex_unix_fdopenr(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd,int binary ATTRIBUTE_UNUSED)969 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
970 		  int binary ATTRIBUTE_UNUSED)
971 {
972   return fdopen (fd, "r");
973 }
974 
975 static FILE *
pex_unix_fdopenw(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd,int binary ATTRIBUTE_UNUSED)976 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
977 		  int binary ATTRIBUTE_UNUSED)
978 {
979   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
980     return NULL;
981   return fdopen (fd, "w");
982 }
983 
984 static void
pex_unix_cleanup(struct pex_obj * obj ATTRIBUTE_UNUSED)985 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
986 {
987 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
988   while (obj->sysdep != NULL)
989     {
990       struct status_list *this;
991       struct status_list *next;
992 
993       this = (struct status_list *) obj->sysdep;
994       next = this->next;
995       free (this);
996       obj->sysdep = (void *) next;
997     }
998 #endif
999 }
1000