1*38fd1498Szrj /* Utilities to execute a program in a subprocess (possibly linked by pipes
2*38fd1498Szrj with other subprocesses), and wait for it. Generic Unix version
3*38fd1498Szrj (also used for UWIN and VMS).
4*38fd1498Szrj Copyright (C) 1996-2018 Free Software Foundation, Inc.
5*38fd1498Szrj
6*38fd1498Szrj This file is part of the libiberty library.
7*38fd1498Szrj Libiberty is free software; you can redistribute it and/or
8*38fd1498Szrj modify it under the terms of the GNU Library General Public
9*38fd1498Szrj License as published by the Free Software Foundation; either
10*38fd1498Szrj version 2 of the License, or (at your option) any later version.
11*38fd1498Szrj
12*38fd1498Szrj Libiberty is distributed in the hope that it will be useful,
13*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
14*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15*38fd1498Szrj Library General Public License for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU Library General Public
18*38fd1498Szrj License along with libiberty; see the file COPYING.LIB. If not,
19*38fd1498Szrj write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20*38fd1498Szrj Boston, MA 02110-1301, USA. */
21*38fd1498Szrj
22*38fd1498Szrj #include "config.h"
23*38fd1498Szrj #include "libiberty.h"
24*38fd1498Szrj #include "pex-common.h"
25*38fd1498Szrj #include "environ.h"
26*38fd1498Szrj
27*38fd1498Szrj #include <stdio.h>
28*38fd1498Szrj #include <signal.h>
29*38fd1498Szrj #include <errno.h>
30*38fd1498Szrj #ifdef NEED_DECLARATION_ERRNO
31*38fd1498Szrj extern int errno;
32*38fd1498Szrj #endif
33*38fd1498Szrj #ifdef HAVE_STDLIB_H
34*38fd1498Szrj #include <stdlib.h>
35*38fd1498Szrj #endif
36*38fd1498Szrj #ifdef HAVE_STRING_H
37*38fd1498Szrj #include <string.h>
38*38fd1498Szrj #endif
39*38fd1498Szrj #ifdef HAVE_UNISTD_H
40*38fd1498Szrj #include <unistd.h>
41*38fd1498Szrj #endif
42*38fd1498Szrj
43*38fd1498Szrj #include <sys/types.h>
44*38fd1498Szrj
45*38fd1498Szrj #ifdef HAVE_FCNTL_H
46*38fd1498Szrj #include <fcntl.h>
47*38fd1498Szrj #endif
48*38fd1498Szrj #ifdef HAVE_SYS_WAIT_H
49*38fd1498Szrj #include <sys/wait.h>
50*38fd1498Szrj #endif
51*38fd1498Szrj #ifdef HAVE_GETRUSAGE
52*38fd1498Szrj #include <sys/time.h>
53*38fd1498Szrj #include <sys/resource.h>
54*38fd1498Szrj #endif
55*38fd1498Szrj #ifdef HAVE_SYS_STAT_H
56*38fd1498Szrj #include <sys/stat.h>
57*38fd1498Szrj #endif
58*38fd1498Szrj #ifdef HAVE_PROCESS_H
59*38fd1498Szrj #include <process.h>
60*38fd1498Szrj #endif
61*38fd1498Szrj
62*38fd1498Szrj #ifdef vfork /* Autoconf may define this to fork for us. */
63*38fd1498Szrj # define VFORK_STRING "fork"
64*38fd1498Szrj #else
65*38fd1498Szrj # define VFORK_STRING "vfork"
66*38fd1498Szrj #endif
67*38fd1498Szrj #ifdef HAVE_VFORK_H
68*38fd1498Szrj #include <vfork.h>
69*38fd1498Szrj #endif
70*38fd1498Szrj #if defined(VMS) && defined (__LONG_POINTERS)
71*38fd1498Szrj #ifndef __CHAR_PTR32
72*38fd1498Szrj typedef char * __char_ptr32
73*38fd1498Szrj __attribute__ ((mode (SI)));
74*38fd1498Szrj #endif
75*38fd1498Szrj
76*38fd1498Szrj typedef __char_ptr32 *__char_ptr_char_ptr32
77*38fd1498Szrj __attribute__ ((mode (SI)));
78*38fd1498Szrj
79*38fd1498Szrj /* Return a 32 bit pointer to an array of 32 bit pointers
80*38fd1498Szrj given a 64 bit pointer to an array of 64 bit pointers. */
81*38fd1498Szrj
82*38fd1498Szrj static __char_ptr_char_ptr32
to_ptr32(char ** ptr64)83*38fd1498Szrj to_ptr32 (char **ptr64)
84*38fd1498Szrj {
85*38fd1498Szrj int argc;
86*38fd1498Szrj __char_ptr_char_ptr32 short_argv;
87*38fd1498Szrj
88*38fd1498Szrj /* Count number of arguments. */
89*38fd1498Szrj for (argc = 0; ptr64[argc] != NULL; argc++)
90*38fd1498Szrj ;
91*38fd1498Szrj
92*38fd1498Szrj /* Reallocate argv with 32 bit pointers. */
93*38fd1498Szrj short_argv = (__char_ptr_char_ptr32) decc$malloc
94*38fd1498Szrj (sizeof (__char_ptr32) * (argc + 1));
95*38fd1498Szrj
96*38fd1498Szrj for (argc = 0; ptr64[argc] != NULL; argc++)
97*38fd1498Szrj short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
98*38fd1498Szrj
99*38fd1498Szrj short_argv[argc] = (__char_ptr32) 0;
100*38fd1498Szrj return short_argv;
101*38fd1498Szrj
102*38fd1498Szrj }
103*38fd1498Szrj #else
104*38fd1498Szrj #define to_ptr32(argv) argv
105*38fd1498Szrj #endif
106*38fd1498Szrj
107*38fd1498Szrj /* File mode to use for private and world-readable files. */
108*38fd1498Szrj
109*38fd1498Szrj #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
110*38fd1498Szrj #define PUBLIC_MODE \
111*38fd1498Szrj (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
112*38fd1498Szrj #else
113*38fd1498Szrj #define PUBLIC_MODE 0666
114*38fd1498Szrj #endif
115*38fd1498Szrj
116*38fd1498Szrj /* Get the exit status of a particular process, and optionally get the
117*38fd1498Szrj time that it took. This is simple if we have wait4, slightly
118*38fd1498Szrj harder if we have waitpid, and is a pain if we only have wait. */
119*38fd1498Szrj
120*38fd1498Szrj static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
121*38fd1498Szrj
122*38fd1498Szrj #ifdef HAVE_WAIT4
123*38fd1498Szrj
124*38fd1498Szrj static pid_t
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)125*38fd1498Szrj pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
126*38fd1498Szrj struct pex_time *time)
127*38fd1498Szrj {
128*38fd1498Szrj pid_t ret;
129*38fd1498Szrj struct rusage r;
130*38fd1498Szrj
131*38fd1498Szrj #ifdef HAVE_WAITPID
132*38fd1498Szrj if (time == NULL)
133*38fd1498Szrj return waitpid (pid, status, 0);
134*38fd1498Szrj #endif
135*38fd1498Szrj
136*38fd1498Szrj ret = wait4 (pid, status, 0, &r);
137*38fd1498Szrj
138*38fd1498Szrj if (time != NULL)
139*38fd1498Szrj {
140*38fd1498Szrj time->user_seconds = r.ru_utime.tv_sec;
141*38fd1498Szrj time->user_microseconds= r.ru_utime.tv_usec;
142*38fd1498Szrj time->system_seconds = r.ru_stime.tv_sec;
143*38fd1498Szrj time->system_microseconds= r.ru_stime.tv_usec;
144*38fd1498Szrj }
145*38fd1498Szrj
146*38fd1498Szrj return ret;
147*38fd1498Szrj }
148*38fd1498Szrj
149*38fd1498Szrj #else /* ! defined (HAVE_WAIT4) */
150*38fd1498Szrj
151*38fd1498Szrj #ifdef HAVE_WAITPID
152*38fd1498Szrj
153*38fd1498Szrj #ifndef HAVE_GETRUSAGE
154*38fd1498Szrj
155*38fd1498Szrj static pid_t
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)156*38fd1498Szrj pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
157*38fd1498Szrj struct pex_time *time)
158*38fd1498Szrj {
159*38fd1498Szrj if (time != NULL)
160*38fd1498Szrj memset (time, 0, sizeof (struct pex_time));
161*38fd1498Szrj return waitpid (pid, status, 0);
162*38fd1498Szrj }
163*38fd1498Szrj
164*38fd1498Szrj #else /* defined (HAVE_GETRUSAGE) */
165*38fd1498Szrj
166*38fd1498Szrj static pid_t
pex_wait(struct pex_obj * obj ATTRIBUTE_UNUSED,pid_t pid,int * status,struct pex_time * time)167*38fd1498Szrj pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
168*38fd1498Szrj struct pex_time *time)
169*38fd1498Szrj {
170*38fd1498Szrj struct rusage r1, r2;
171*38fd1498Szrj pid_t ret;
172*38fd1498Szrj
173*38fd1498Szrj if (time == NULL)
174*38fd1498Szrj return waitpid (pid, status, 0);
175*38fd1498Szrj
176*38fd1498Szrj getrusage (RUSAGE_CHILDREN, &r1);
177*38fd1498Szrj
178*38fd1498Szrj ret = waitpid (pid, status, 0);
179*38fd1498Szrj if (ret < 0)
180*38fd1498Szrj return ret;
181*38fd1498Szrj
182*38fd1498Szrj getrusage (RUSAGE_CHILDREN, &r2);
183*38fd1498Szrj
184*38fd1498Szrj time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
185*38fd1498Szrj time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
186*38fd1498Szrj if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
187*38fd1498Szrj {
188*38fd1498Szrj --time->user_seconds;
189*38fd1498Szrj time->user_microseconds += 1000000;
190*38fd1498Szrj }
191*38fd1498Szrj
192*38fd1498Szrj time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
193*38fd1498Szrj time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
194*38fd1498Szrj if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
195*38fd1498Szrj {
196*38fd1498Szrj --time->system_seconds;
197*38fd1498Szrj time->system_microseconds += 1000000;
198*38fd1498Szrj }
199*38fd1498Szrj
200*38fd1498Szrj return ret;
201*38fd1498Szrj }
202*38fd1498Szrj
203*38fd1498Szrj #endif /* defined (HAVE_GETRUSAGE) */
204*38fd1498Szrj
205*38fd1498Szrj #else /* ! defined (HAVE_WAITPID) */
206*38fd1498Szrj
207*38fd1498Szrj struct status_list
208*38fd1498Szrj {
209*38fd1498Szrj struct status_list *next;
210*38fd1498Szrj pid_t pid;
211*38fd1498Szrj int status;
212*38fd1498Szrj struct pex_time time;
213*38fd1498Szrj };
214*38fd1498Szrj
215*38fd1498Szrj static pid_t
pex_wait(struct pex_obj * obj,pid_t pid,int * status,struct pex_time * time)216*38fd1498Szrj pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
217*38fd1498Szrj {
218*38fd1498Szrj struct status_list **pp;
219*38fd1498Szrj
220*38fd1498Szrj for (pp = (struct status_list **) &obj->sysdep;
221*38fd1498Szrj *pp != NULL;
222*38fd1498Szrj pp = &(*pp)->next)
223*38fd1498Szrj {
224*38fd1498Szrj if ((*pp)->pid == pid)
225*38fd1498Szrj {
226*38fd1498Szrj struct status_list *p;
227*38fd1498Szrj
228*38fd1498Szrj p = *pp;
229*38fd1498Szrj *status = p->status;
230*38fd1498Szrj if (time != NULL)
231*38fd1498Szrj *time = p->time;
232*38fd1498Szrj *pp = p->next;
233*38fd1498Szrj free (p);
234*38fd1498Szrj return pid;
235*38fd1498Szrj }
236*38fd1498Szrj }
237*38fd1498Szrj
238*38fd1498Szrj while (1)
239*38fd1498Szrj {
240*38fd1498Szrj pid_t cpid;
241*38fd1498Szrj struct status_list *psl;
242*38fd1498Szrj struct pex_time pt;
243*38fd1498Szrj #ifdef HAVE_GETRUSAGE
244*38fd1498Szrj struct rusage r1, r2;
245*38fd1498Szrj #endif
246*38fd1498Szrj
247*38fd1498Szrj if (time != NULL)
248*38fd1498Szrj {
249*38fd1498Szrj #ifdef HAVE_GETRUSAGE
250*38fd1498Szrj getrusage (RUSAGE_CHILDREN, &r1);
251*38fd1498Szrj #else
252*38fd1498Szrj memset (&pt, 0, sizeof (struct pex_time));
253*38fd1498Szrj #endif
254*38fd1498Szrj }
255*38fd1498Szrj
256*38fd1498Szrj cpid = wait (status);
257*38fd1498Szrj
258*38fd1498Szrj #ifdef HAVE_GETRUSAGE
259*38fd1498Szrj if (time != NULL && cpid >= 0)
260*38fd1498Szrj {
261*38fd1498Szrj getrusage (RUSAGE_CHILDREN, &r2);
262*38fd1498Szrj
263*38fd1498Szrj pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
264*38fd1498Szrj pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
265*38fd1498Szrj if (pt.user_microseconds < 0)
266*38fd1498Szrj {
267*38fd1498Szrj --pt.user_seconds;
268*38fd1498Szrj pt.user_microseconds += 1000000;
269*38fd1498Szrj }
270*38fd1498Szrj
271*38fd1498Szrj pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
272*38fd1498Szrj pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
273*38fd1498Szrj if (pt.system_microseconds < 0)
274*38fd1498Szrj {
275*38fd1498Szrj --pt.system_seconds;
276*38fd1498Szrj pt.system_microseconds += 1000000;
277*38fd1498Szrj }
278*38fd1498Szrj }
279*38fd1498Szrj #endif
280*38fd1498Szrj
281*38fd1498Szrj if (cpid < 0 || cpid == pid)
282*38fd1498Szrj {
283*38fd1498Szrj if (time != NULL)
284*38fd1498Szrj *time = pt;
285*38fd1498Szrj return cpid;
286*38fd1498Szrj }
287*38fd1498Szrj
288*38fd1498Szrj psl = XNEW (struct status_list);
289*38fd1498Szrj psl->pid = cpid;
290*38fd1498Szrj psl->status = *status;
291*38fd1498Szrj if (time != NULL)
292*38fd1498Szrj psl->time = pt;
293*38fd1498Szrj psl->next = (struct status_list *) obj->sysdep;
294*38fd1498Szrj obj->sysdep = (void *) psl;
295*38fd1498Szrj }
296*38fd1498Szrj }
297*38fd1498Szrj
298*38fd1498Szrj #endif /* ! defined (HAVE_WAITPID) */
299*38fd1498Szrj #endif /* ! defined (HAVE_WAIT4) */
300*38fd1498Szrj
301*38fd1498Szrj static void pex_child_error (struct pex_obj *, const char *, const char *, int)
302*38fd1498Szrj ATTRIBUTE_NORETURN;
303*38fd1498Szrj static int pex_unix_open_read (struct pex_obj *, const char *, int);
304*38fd1498Szrj static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
305*38fd1498Szrj static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
306*38fd1498Szrj char * const *, char * const *,
307*38fd1498Szrj int, int, int, int,
308*38fd1498Szrj const char **, int *);
309*38fd1498Szrj static int pex_unix_close (struct pex_obj *, int);
310*38fd1498Szrj static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
311*38fd1498Szrj int, const char **, int *);
312*38fd1498Szrj static int pex_unix_pipe (struct pex_obj *, int *, int);
313*38fd1498Szrj static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
314*38fd1498Szrj static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
315*38fd1498Szrj static void pex_unix_cleanup (struct pex_obj *);
316*38fd1498Szrj
317*38fd1498Szrj /* The list of functions we pass to the common routines. */
318*38fd1498Szrj
319*38fd1498Szrj const struct pex_funcs funcs =
320*38fd1498Szrj {
321*38fd1498Szrj pex_unix_open_read,
322*38fd1498Szrj pex_unix_open_write,
323*38fd1498Szrj pex_unix_exec_child,
324*38fd1498Szrj pex_unix_close,
325*38fd1498Szrj pex_unix_wait,
326*38fd1498Szrj pex_unix_pipe,
327*38fd1498Szrj pex_unix_fdopenr,
328*38fd1498Szrj pex_unix_fdopenw,
329*38fd1498Szrj pex_unix_cleanup
330*38fd1498Szrj };
331*38fd1498Szrj
332*38fd1498Szrj /* Return a newly initialized pex_obj structure. */
333*38fd1498Szrj
334*38fd1498Szrj struct pex_obj *
pex_init(int flags,const char * pname,const char * tempbase)335*38fd1498Szrj pex_init (int flags, const char *pname, const char *tempbase)
336*38fd1498Szrj {
337*38fd1498Szrj return pex_init_common (flags, pname, tempbase, &funcs);
338*38fd1498Szrj }
339*38fd1498Szrj
340*38fd1498Szrj /* Open a file for reading. */
341*38fd1498Szrj
342*38fd1498Szrj static int
pex_unix_open_read(struct pex_obj * obj ATTRIBUTE_UNUSED,const char * name,int binary ATTRIBUTE_UNUSED)343*38fd1498Szrj pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
344*38fd1498Szrj int binary ATTRIBUTE_UNUSED)
345*38fd1498Szrj {
346*38fd1498Szrj return open (name, O_RDONLY);
347*38fd1498Szrj }
348*38fd1498Szrj
349*38fd1498Szrj /* Open a file for writing. */
350*38fd1498Szrj
351*38fd1498Szrj static int
pex_unix_open_write(struct pex_obj * obj ATTRIBUTE_UNUSED,const char * name,int binary ATTRIBUTE_UNUSED,int append)352*38fd1498Szrj pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
353*38fd1498Szrj int binary ATTRIBUTE_UNUSED, int append)
354*38fd1498Szrj {
355*38fd1498Szrj /* Note that we can't use O_EXCL here because gcc may have already
356*38fd1498Szrj created the temporary file via make_temp_file. */
357*38fd1498Szrj return open (name, O_WRONLY | O_CREAT
358*38fd1498Szrj | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE);
359*38fd1498Szrj }
360*38fd1498Szrj
361*38fd1498Szrj /* Close a file. */
362*38fd1498Szrj
363*38fd1498Szrj static int
pex_unix_close(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd)364*38fd1498Szrj pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
365*38fd1498Szrj {
366*38fd1498Szrj return close (fd);
367*38fd1498Szrj }
368*38fd1498Szrj
369*38fd1498Szrj /* Report an error from a child process. We don't use stdio routines,
370*38fd1498Szrj because we might be here due to a vfork call. */
371*38fd1498Szrj
372*38fd1498Szrj static void
pex_child_error(struct pex_obj * obj,const char * executable,const char * errmsg,int err)373*38fd1498Szrj pex_child_error (struct pex_obj *obj, const char *executable,
374*38fd1498Szrj const char *errmsg, int err)
375*38fd1498Szrj {
376*38fd1498Szrj int retval = 0;
377*38fd1498Szrj #define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
378*38fd1498Szrj writeerr (obj->pname);
379*38fd1498Szrj writeerr (": error trying to exec '");
380*38fd1498Szrj writeerr (executable);
381*38fd1498Szrj writeerr ("': ");
382*38fd1498Szrj writeerr (errmsg);
383*38fd1498Szrj writeerr (": ");
384*38fd1498Szrj writeerr (xstrerror (err));
385*38fd1498Szrj writeerr ("\n");
386*38fd1498Szrj #undef writeerr
387*38fd1498Szrj /* Exit with -2 if the error output failed, too. */
388*38fd1498Szrj _exit (retval == 0 ? -1 : -2);
389*38fd1498Szrj }
390*38fd1498Szrj
391*38fd1498Szrj /* Execute a child. */
392*38fd1498Szrj
393*38fd1498Szrj #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
394*38fd1498Szrj /* Implementation of pex->exec_child using the Cygwin spawn operation. */
395*38fd1498Szrj
396*38fd1498Szrj /* Subroutine of pex_unix_exec_child. Move OLD_FD to a new file descriptor
397*38fd1498Szrj to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the
398*38fd1498Szrj saved copy to be close-on-exec. Move CHILD_FD into OLD_FD. If CHILD_FD
399*38fd1498Szrj is -1, OLD_FD is to be closed. Return -1 on error. */
400*38fd1498Szrj
401*38fd1498Szrj static int
save_and_install_fd(int * pnew_fd,int * pflags,int old_fd,int child_fd)402*38fd1498Szrj save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd)
403*38fd1498Szrj {
404*38fd1498Szrj int new_fd, flags;
405*38fd1498Szrj
406*38fd1498Szrj flags = fcntl (old_fd, F_GETFD);
407*38fd1498Szrj
408*38fd1498Szrj /* If we could not retrieve the flags, then OLD_FD was not open. */
409*38fd1498Szrj if (flags < 0)
410*38fd1498Szrj {
411*38fd1498Szrj new_fd = -1, flags = 0;
412*38fd1498Szrj if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0)
413*38fd1498Szrj return -1;
414*38fd1498Szrj }
415*38fd1498Szrj /* If we wish to close OLD_FD, just mark it CLOEXEC. */
416*38fd1498Szrj else if (child_fd == -1)
417*38fd1498Szrj {
418*38fd1498Szrj new_fd = old_fd;
419*38fd1498Szrj if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0)
420*38fd1498Szrj return -1;
421*38fd1498Szrj }
422*38fd1498Szrj /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD. */
423*38fd1498Szrj else
424*38fd1498Szrj {
425*38fd1498Szrj #ifdef F_DUPFD_CLOEXEC
426*38fd1498Szrj new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3);
427*38fd1498Szrj if (new_fd < 0)
428*38fd1498Szrj return -1;
429*38fd1498Szrj #else
430*38fd1498Szrj /* Prefer F_DUPFD over dup in order to avoid getting a new fd
431*38fd1498Szrj in the range 0-2, right where a new stderr fd might get put. */
432*38fd1498Szrj new_fd = fcntl (old_fd, F_DUPFD, 3);
433*38fd1498Szrj if (new_fd < 0)
434*38fd1498Szrj return -1;
435*38fd1498Szrj if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0)
436*38fd1498Szrj return -1;
437*38fd1498Szrj #endif
438*38fd1498Szrj if (dup2 (child_fd, old_fd) < 0)
439*38fd1498Szrj return -1;
440*38fd1498Szrj }
441*38fd1498Szrj
442*38fd1498Szrj *pflags = flags;
443*38fd1498Szrj if (pnew_fd)
444*38fd1498Szrj *pnew_fd = new_fd;
445*38fd1498Szrj else if (new_fd != old_fd)
446*38fd1498Szrj abort ();
447*38fd1498Szrj
448*38fd1498Szrj return 0;
449*38fd1498Szrj }
450*38fd1498Szrj
451*38fd1498Szrj /* Subroutine of pex_unix_exec_child. Move SAVE_FD back to OLD_FD
452*38fd1498Szrj restoring FLAGS. If SAVE_FD < 0, OLD_FD is to be closed. */
453*38fd1498Szrj
454*38fd1498Szrj static int
restore_fd(int old_fd,int save_fd,int flags)455*38fd1498Szrj restore_fd(int old_fd, int save_fd, int flags)
456*38fd1498Szrj {
457*38fd1498Szrj /* For SAVE_FD < 0, all we have to do is restore the
458*38fd1498Szrj "closed-ness" of the original. */
459*38fd1498Szrj if (save_fd < 0)
460*38fd1498Szrj return close (old_fd);
461*38fd1498Szrj
462*38fd1498Szrj /* For SAVE_FD == OLD_FD, all we have to do is restore the
463*38fd1498Szrj original setting of the CLOEXEC flag. */
464*38fd1498Szrj if (save_fd == old_fd)
465*38fd1498Szrj {
466*38fd1498Szrj if (flags & FD_CLOEXEC)
467*38fd1498Szrj return 0;
468*38fd1498Szrj return fcntl (old_fd, F_SETFD, flags);
469*38fd1498Szrj }
470*38fd1498Szrj
471*38fd1498Szrj /* Otherwise we have to move the descriptor back, restore the flags,
472*38fd1498Szrj and close the saved copy. */
473*38fd1498Szrj #ifdef HAVE_DUP3
474*38fd1498Szrj if (flags == FD_CLOEXEC)
475*38fd1498Szrj {
476*38fd1498Szrj if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0)
477*38fd1498Szrj return -1;
478*38fd1498Szrj }
479*38fd1498Szrj else
480*38fd1498Szrj #endif
481*38fd1498Szrj {
482*38fd1498Szrj if (dup2 (save_fd, old_fd) < 0)
483*38fd1498Szrj return -1;
484*38fd1498Szrj if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0)
485*38fd1498Szrj return -1;
486*38fd1498Szrj }
487*38fd1498Szrj return close (save_fd);
488*38fd1498Szrj }
489*38fd1498Szrj
490*38fd1498Szrj 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)491*38fd1498Szrj pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED,
492*38fd1498Szrj int flags, const char *executable,
493*38fd1498Szrj char * const * argv, char * const * env,
494*38fd1498Szrj int in, int out, int errdes, int toclose,
495*38fd1498Szrj const char **errmsg, int *err)
496*38fd1498Szrj {
497*38fd1498Szrj int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0;
498*38fd1498Szrj int save_in = -1, save_out = -1, save_err = -1;
499*38fd1498Szrj int max, retries;
500*38fd1498Szrj pid_t pid;
501*38fd1498Szrj
502*38fd1498Szrj if (flags & PEX_STDERR_TO_STDOUT)
503*38fd1498Szrj errdes = out;
504*38fd1498Szrj
505*38fd1498Szrj /* We need the three standard file descriptors to be set up as for
506*38fd1498Szrj the child before we perform the spawn. The file descriptors for
507*38fd1498Szrj the parent need to be moved and marked for close-on-exec. */
508*38fd1498Szrj if (in != STDIN_FILE_NO
509*38fd1498Szrj && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0)
510*38fd1498Szrj goto error_dup2;
511*38fd1498Szrj if (out != STDOUT_FILE_NO
512*38fd1498Szrj && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0)
513*38fd1498Szrj goto error_dup2;
514*38fd1498Szrj if (errdes != STDERR_FILE_NO
515*38fd1498Szrj && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0)
516*38fd1498Szrj goto error_dup2;
517*38fd1498Szrj if (toclose >= 0
518*38fd1498Szrj && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0)
519*38fd1498Szrj goto error_dup2;
520*38fd1498Szrj
521*38fd1498Szrj /* Now that we've moved the file descriptors for the child into place,
522*38fd1498Szrj close the originals. Be careful not to close any of the standard
523*38fd1498Szrj file descriptors that we just set up. */
524*38fd1498Szrj max = -1;
525*38fd1498Szrj if (errdes >= 0)
526*38fd1498Szrj max = STDERR_FILE_NO;
527*38fd1498Szrj else if (out >= 0)
528*38fd1498Szrj max = STDOUT_FILE_NO;
529*38fd1498Szrj else if (in >= 0)
530*38fd1498Szrj max = STDIN_FILE_NO;
531*38fd1498Szrj if (in > max)
532*38fd1498Szrj close (in);
533*38fd1498Szrj if (out > max)
534*38fd1498Szrj close (out);
535*38fd1498Szrj if (errdes > max && errdes != out)
536*38fd1498Szrj close (errdes);
537*38fd1498Szrj
538*38fd1498Szrj /* If we were not given an environment, use the global environment. */
539*38fd1498Szrj if (env == NULL)
540*38fd1498Szrj env = environ;
541*38fd1498Szrj
542*38fd1498Szrj /* Launch the program. If we get EAGAIN (normally out of pid's), try
543*38fd1498Szrj again a few times with increasing backoff times. */
544*38fd1498Szrj retries = 0;
545*38fd1498Szrj while (1)
546*38fd1498Szrj {
547*38fd1498Szrj typedef const char * const *cc_cp;
548*38fd1498Szrj
549*38fd1498Szrj if (flags & PEX_SEARCH)
550*38fd1498Szrj pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
551*38fd1498Szrj else
552*38fd1498Szrj pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env);
553*38fd1498Szrj
554*38fd1498Szrj if (pid > 0)
555*38fd1498Szrj break;
556*38fd1498Szrj
557*38fd1498Szrj *err = errno;
558*38fd1498Szrj *errmsg = "spawn";
559*38fd1498Szrj if (errno != EAGAIN || ++retries == 4)
560*38fd1498Szrj return (pid_t) -1;
561*38fd1498Szrj sleep (1 << retries);
562*38fd1498Szrj }
563*38fd1498Szrj
564*38fd1498Szrj /* Success. Restore the parent's file descriptors that we saved above. */
565*38fd1498Szrj if (toclose >= 0
566*38fd1498Szrj && restore_fd (toclose, toclose, fl_tc) < 0)
567*38fd1498Szrj goto error_dup2;
568*38fd1498Szrj if (in != STDIN_FILE_NO
569*38fd1498Szrj && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0)
570*38fd1498Szrj goto error_dup2;
571*38fd1498Szrj if (out != STDOUT_FILE_NO
572*38fd1498Szrj && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0)
573*38fd1498Szrj goto error_dup2;
574*38fd1498Szrj if (errdes != STDERR_FILE_NO
575*38fd1498Szrj && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0)
576*38fd1498Szrj goto error_dup2;
577*38fd1498Szrj
578*38fd1498Szrj return pid;
579*38fd1498Szrj
580*38fd1498Szrj error_dup2:
581*38fd1498Szrj *err = errno;
582*38fd1498Szrj *errmsg = "dup2";
583*38fd1498Szrj return (pid_t) -1;
584*38fd1498Szrj }
585*38fd1498Szrj
586*38fd1498Szrj #else
587*38fd1498Szrj /* Implementation of pex->exec_child using standard vfork + exec. */
588*38fd1498Szrj
589*38fd1498Szrj 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)590*38fd1498Szrj pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
591*38fd1498Szrj char * const * argv, char * const * env,
592*38fd1498Szrj int in, int out, int errdes,
593*38fd1498Szrj int toclose, const char **errmsg, int *err)
594*38fd1498Szrj {
595*38fd1498Szrj pid_t pid;
596*38fd1498Szrj
597*38fd1498Szrj /* We declare these to be volatile to avoid warnings from gcc about
598*38fd1498Szrj them being clobbered by vfork. */
599*38fd1498Szrj volatile int sleep_interval;
600*38fd1498Szrj volatile int retries;
601*38fd1498Szrj
602*38fd1498Szrj /* We vfork and then set environ in the child before calling execvp.
603*38fd1498Szrj This clobbers the parent's environ so we need to restore it.
604*38fd1498Szrj It would be nice to use one of the exec* functions that takes an
605*38fd1498Szrj environment as a parameter, but that may have portability issues. */
606*38fd1498Szrj char **save_environ = environ;
607*38fd1498Szrj
608*38fd1498Szrj sleep_interval = 1;
609*38fd1498Szrj pid = -1;
610*38fd1498Szrj for (retries = 0; retries < 4; ++retries)
611*38fd1498Szrj {
612*38fd1498Szrj pid = vfork ();
613*38fd1498Szrj if (pid >= 0)
614*38fd1498Szrj break;
615*38fd1498Szrj sleep (sleep_interval);
616*38fd1498Szrj sleep_interval *= 2;
617*38fd1498Szrj }
618*38fd1498Szrj
619*38fd1498Szrj switch (pid)
620*38fd1498Szrj {
621*38fd1498Szrj case -1:
622*38fd1498Szrj *err = errno;
623*38fd1498Szrj *errmsg = VFORK_STRING;
624*38fd1498Szrj return (pid_t) -1;
625*38fd1498Szrj
626*38fd1498Szrj case 0:
627*38fd1498Szrj /* Child process. */
628*38fd1498Szrj if (in != STDIN_FILE_NO)
629*38fd1498Szrj {
630*38fd1498Szrj if (dup2 (in, STDIN_FILE_NO) < 0)
631*38fd1498Szrj pex_child_error (obj, executable, "dup2", errno);
632*38fd1498Szrj if (close (in) < 0)
633*38fd1498Szrj pex_child_error (obj, executable, "close", errno);
634*38fd1498Szrj }
635*38fd1498Szrj if (out != STDOUT_FILE_NO)
636*38fd1498Szrj {
637*38fd1498Szrj if (dup2 (out, STDOUT_FILE_NO) < 0)
638*38fd1498Szrj pex_child_error (obj, executable, "dup2", errno);
639*38fd1498Szrj if (close (out) < 0)
640*38fd1498Szrj pex_child_error (obj, executable, "close", errno);
641*38fd1498Szrj }
642*38fd1498Szrj if (errdes != STDERR_FILE_NO)
643*38fd1498Szrj {
644*38fd1498Szrj if (dup2 (errdes, STDERR_FILE_NO) < 0)
645*38fd1498Szrj pex_child_error (obj, executable, "dup2", errno);
646*38fd1498Szrj if (close (errdes) < 0)
647*38fd1498Szrj pex_child_error (obj, executable, "close", errno);
648*38fd1498Szrj }
649*38fd1498Szrj if (toclose >= 0)
650*38fd1498Szrj {
651*38fd1498Szrj if (close (toclose) < 0)
652*38fd1498Szrj pex_child_error (obj, executable, "close", errno);
653*38fd1498Szrj }
654*38fd1498Szrj if ((flags & PEX_STDERR_TO_STDOUT) != 0)
655*38fd1498Szrj {
656*38fd1498Szrj if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
657*38fd1498Szrj pex_child_error (obj, executable, "dup2", errno);
658*38fd1498Szrj }
659*38fd1498Szrj
660*38fd1498Szrj if (env)
661*38fd1498Szrj {
662*38fd1498Szrj /* NOTE: In a standard vfork implementation this clobbers the
663*38fd1498Szrj parent's copy of environ "too" (in reality there's only one copy).
664*38fd1498Szrj This is ok as we restore it below. */
665*38fd1498Szrj environ = (char**) env;
666*38fd1498Szrj }
667*38fd1498Szrj
668*38fd1498Szrj if ((flags & PEX_SEARCH) != 0)
669*38fd1498Szrj {
670*38fd1498Szrj execvp (executable, to_ptr32 (argv));
671*38fd1498Szrj pex_child_error (obj, executable, "execvp", errno);
672*38fd1498Szrj }
673*38fd1498Szrj else
674*38fd1498Szrj {
675*38fd1498Szrj execv (executable, to_ptr32 (argv));
676*38fd1498Szrj pex_child_error (obj, executable, "execv", errno);
677*38fd1498Szrj }
678*38fd1498Szrj
679*38fd1498Szrj /* NOTREACHED */
680*38fd1498Szrj return (pid_t) -1;
681*38fd1498Szrj
682*38fd1498Szrj default:
683*38fd1498Szrj /* Parent process. */
684*38fd1498Szrj
685*38fd1498Szrj /* Restore environ.
686*38fd1498Szrj Note that the parent either doesn't run until the child execs/exits
687*38fd1498Szrj (standard vfork behaviour), or if it does run then vfork is behaving
688*38fd1498Szrj more like fork. In either case we needn't worry about clobbering
689*38fd1498Szrj the child's copy of environ. */
690*38fd1498Szrj environ = save_environ;
691*38fd1498Szrj
692*38fd1498Szrj if (in != STDIN_FILE_NO)
693*38fd1498Szrj {
694*38fd1498Szrj if (close (in) < 0)
695*38fd1498Szrj {
696*38fd1498Szrj *err = errno;
697*38fd1498Szrj *errmsg = "close";
698*38fd1498Szrj return (pid_t) -1;
699*38fd1498Szrj }
700*38fd1498Szrj }
701*38fd1498Szrj if (out != STDOUT_FILE_NO)
702*38fd1498Szrj {
703*38fd1498Szrj if (close (out) < 0)
704*38fd1498Szrj {
705*38fd1498Szrj *err = errno;
706*38fd1498Szrj *errmsg = "close";
707*38fd1498Szrj return (pid_t) -1;
708*38fd1498Szrj }
709*38fd1498Szrj }
710*38fd1498Szrj if (errdes != STDERR_FILE_NO)
711*38fd1498Szrj {
712*38fd1498Szrj if (close (errdes) < 0)
713*38fd1498Szrj {
714*38fd1498Szrj *err = errno;
715*38fd1498Szrj *errmsg = "close";
716*38fd1498Szrj return (pid_t) -1;
717*38fd1498Szrj }
718*38fd1498Szrj }
719*38fd1498Szrj
720*38fd1498Szrj return pid;
721*38fd1498Szrj }
722*38fd1498Szrj }
723*38fd1498Szrj #endif /* SPAWN */
724*38fd1498Szrj
725*38fd1498Szrj /* Wait for a child process to complete. */
726*38fd1498Szrj
727*38fd1498Szrj static int
pex_unix_wait(struct pex_obj * obj,pid_t pid,int * status,struct pex_time * time,int done,const char ** errmsg,int * err)728*38fd1498Szrj pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
729*38fd1498Szrj struct pex_time *time, int done, const char **errmsg,
730*38fd1498Szrj int *err)
731*38fd1498Szrj {
732*38fd1498Szrj /* If we are cleaning up when the caller didn't retrieve process
733*38fd1498Szrj status for some reason, encourage the process to go away. */
734*38fd1498Szrj if (done)
735*38fd1498Szrj kill (pid, SIGTERM);
736*38fd1498Szrj
737*38fd1498Szrj if (pex_wait (obj, pid, status, time) < 0)
738*38fd1498Szrj {
739*38fd1498Szrj *err = errno;
740*38fd1498Szrj *errmsg = "wait";
741*38fd1498Szrj return -1;
742*38fd1498Szrj }
743*38fd1498Szrj
744*38fd1498Szrj return 0;
745*38fd1498Szrj }
746*38fd1498Szrj
747*38fd1498Szrj /* Create a pipe. */
748*38fd1498Szrj
749*38fd1498Szrj static int
pex_unix_pipe(struct pex_obj * obj ATTRIBUTE_UNUSED,int * p,int binary ATTRIBUTE_UNUSED)750*38fd1498Szrj pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
751*38fd1498Szrj int binary ATTRIBUTE_UNUSED)
752*38fd1498Szrj {
753*38fd1498Szrj return pipe (p);
754*38fd1498Szrj }
755*38fd1498Szrj
756*38fd1498Szrj /* Get a FILE pointer to read from a file descriptor. */
757*38fd1498Szrj
758*38fd1498Szrj static FILE *
pex_unix_fdopenr(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd,int binary ATTRIBUTE_UNUSED)759*38fd1498Szrj pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
760*38fd1498Szrj int binary ATTRIBUTE_UNUSED)
761*38fd1498Szrj {
762*38fd1498Szrj return fdopen (fd, "r");
763*38fd1498Szrj }
764*38fd1498Szrj
765*38fd1498Szrj static FILE *
pex_unix_fdopenw(struct pex_obj * obj ATTRIBUTE_UNUSED,int fd,int binary ATTRIBUTE_UNUSED)766*38fd1498Szrj pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
767*38fd1498Szrj int binary ATTRIBUTE_UNUSED)
768*38fd1498Szrj {
769*38fd1498Szrj if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
770*38fd1498Szrj return NULL;
771*38fd1498Szrj return fdopen (fd, "w");
772*38fd1498Szrj }
773*38fd1498Szrj
774*38fd1498Szrj static void
pex_unix_cleanup(struct pex_obj * obj ATTRIBUTE_UNUSED)775*38fd1498Szrj pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
776*38fd1498Szrj {
777*38fd1498Szrj #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
778*38fd1498Szrj while (obj->sysdep != NULL)
779*38fd1498Szrj {
780*38fd1498Szrj struct status_list *this;
781*38fd1498Szrj struct status_list *next;
782*38fd1498Szrj
783*38fd1498Szrj this = (struct status_list *) obj->sysdep;
784*38fd1498Szrj next = this->next;
785*38fd1498Szrj free (this);
786*38fd1498Szrj obj->sysdep = (void *) next;
787*38fd1498Szrj }
788*38fd1498Szrj #endif
789*38fd1498Szrj }
790