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