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