pex-unix.c revision 1.11 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.11 christos goto exit;
699 1.11 christos }
700 1.11 christos }
701 1.11 christos else
702 1.11 christos {
703 1.11 christos ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ);
704 1.11 christos if (ret)
705 1.11 christos {
706 1.11 christos *err = ret;
707 1.11 christos *errmsg = "posix_spawn";
708 1.11 christos goto exit;
709 1.11 christos }
710 1.11 christos }
711 1.11 christos
712 1.11 christos exit:
713 1.11 christos if (actions_initialized)
714 1.11 christos posix_spawn_file_actions_destroy (&actions);
715 1.11 christos if (attr_initialized)
716 1.11 christos posix_spawnattr_destroy (&attr);
717 1.11 christos
718 1.11 christos if (!*err && in != STDIN_FILE_NO)
719 1.11 christos if (close (in))
720 1.11 christos *errmsg = "close", *err = errno, pid = -1;
721 1.11 christos if (!*err && out != STDOUT_FILE_NO)
722 1.11 christos if (close (out))
723 1.11 christos *errmsg = "close", *err = errno, pid = -1;
724 1.11 christos if (!*err && errdes != STDERR_FILE_NO)
725 1.11 christos if (close (errdes))
726 1.11 christos *errmsg = "close", *err = errno, pid = -1;
727 1.11 christos
728 1.11 christos return pid;
729 1.11 christos }
730 1.1 christos #else
731 1.1 christos /* Implementation of pex->exec_child using standard vfork + exec. */
732 1.1 christos
733 1.1 christos static pid_t
734 1.1 christos pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
735 1.1 christos char * const * argv, char * const * env,
736 1.1 christos int in, int out, int errdes,
737 1.1 christos int toclose, const char **errmsg, int *err)
738 1.1 christos {
739 1.8 christos pid_t pid = -1;
740 1.8 christos /* Tuple to communicate error from child to parent. We can safely
741 1.8 christos transfer string literal pointers as both run with identical
742 1.8 christos address mappings. */
743 1.8 christos struct fn_err
744 1.8 christos {
745 1.8 christos const char *fn;
746 1.8 christos int err;
747 1.8 christos };
748 1.8 christos volatile int do_pipe = 0;
749 1.8 christos volatile int pipes[2]; /* [0]:reader,[1]:writer. */
750 1.8 christos #ifdef O_CLOEXEC
751 1.8 christos do_pipe = 1;
752 1.8 christos #endif
753 1.8 christos if (do_pipe)
754 1.8 christos {
755 1.8 christos #ifdef HAVE_PIPE2
756 1.8 christos if (pipe2 ((int *)pipes, O_CLOEXEC))
757 1.8 christos do_pipe = 0;
758 1.8 christos #else
759 1.8 christos if (pipe ((int *)pipes))
760 1.8 christos do_pipe = 0;
761 1.8 christos else
762 1.8 christos {
763 1.8 christos if (fcntl (pipes[1], F_SETFD, FD_CLOEXEC) == -1)
764 1.8 christos {
765 1.8 christos close (pipes[0]);
766 1.8 christos close (pipes[1]);
767 1.8 christos do_pipe = 0;
768 1.8 christos }
769 1.8 christos }
770 1.8 christos #endif
771 1.8 christos }
772 1.1 christos
773 1.1 christos /* We declare these to be volatile to avoid warnings from gcc about
774 1.1 christos them being clobbered by vfork. */
775 1.8 christos volatile int sleep_interval = 1;
776 1.1 christos volatile int retries;
777 1.1 christos
778 1.1 christos /* We vfork and then set environ in the child before calling execvp.
779 1.1 christos This clobbers the parent's environ so we need to restore it.
780 1.1 christos It would be nice to use one of the exec* functions that takes an
781 1.8 christos environment as a parameter, but that may have portability
782 1.8 christos issues. It is marked volatile so the child doesn't consider it a
783 1.8 christos dead variable and therefore clobber where ever it is stored. */
784 1.8 christos char **volatile save_environ = environ;
785 1.1 christos
786 1.1 christos for (retries = 0; retries < 4; ++retries)
787 1.1 christos {
788 1.1 christos pid = vfork ();
789 1.1 christos if (pid >= 0)
790 1.1 christos break;
791 1.1 christos sleep (sleep_interval);
792 1.1 christos sleep_interval *= 2;
793 1.1 christos }
794 1.1 christos
795 1.1 christos switch (pid)
796 1.1 christos {
797 1.1 christos case -1:
798 1.8 christos if (do_pipe)
799 1.8 christos {
800 1.8 christos close (pipes[0]);
801 1.8 christos close (pipes[1]);
802 1.8 christos }
803 1.1 christos *err = errno;
804 1.1 christos *errmsg = VFORK_STRING;
805 1.1 christos return (pid_t) -1;
806 1.1 christos
807 1.1 christos case 0:
808 1.1 christos /* Child process. */
809 1.8 christos {
810 1.8 christos struct fn_err failed;
811 1.8 christos failed.fn = NULL;
812 1.8 christos
813 1.8 christos if (do_pipe)
814 1.8 christos close (pipes[0]);
815 1.8 christos if (!failed.fn && in != STDIN_FILE_NO)
816 1.8 christos {
817 1.8 christos if (dup2 (in, STDIN_FILE_NO) < 0)
818 1.8 christos failed.fn = "dup2", failed.err = errno;
819 1.8 christos else if (close (in) < 0)
820 1.8 christos failed.fn = "close", failed.err = errno;
821 1.8 christos }
822 1.8 christos if (!failed.fn && out != STDOUT_FILE_NO)
823 1.8 christos {
824 1.8 christos if (dup2 (out, STDOUT_FILE_NO) < 0)
825 1.8 christos failed.fn = "dup2", failed.err = errno;
826 1.8 christos else if (close (out) < 0)
827 1.8 christos failed.fn = "close", failed.err = errno;
828 1.8 christos }
829 1.8 christos if (!failed.fn && errdes != STDERR_FILE_NO)
830 1.8 christos {
831 1.8 christos if (dup2 (errdes, STDERR_FILE_NO) < 0)
832 1.8 christos failed.fn = "dup2", failed.err = errno;
833 1.8 christos else if (close (errdes) < 0)
834 1.8 christos failed.fn = "close", failed.err = errno;
835 1.8 christos }
836 1.8 christos if (!failed.fn && toclose >= 0)
837 1.8 christos {
838 1.8 christos if (close (toclose) < 0)
839 1.8 christos failed.fn = "close", failed.err = errno;
840 1.8 christos }
841 1.8 christos if (!failed.fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
842 1.8 christos {
843 1.8 christos if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
844 1.8 christos failed.fn = "dup2", failed.err = errno;
845 1.8 christos }
846 1.8 christos if (!failed.fn)
847 1.8 christos {
848 1.8 christos if (env)
849 1.8 christos /* NOTE: In a standard vfork implementation this clobbers
850 1.8 christos the parent's copy of environ "too" (in reality there's
851 1.8 christos only one copy). This is ok as we restore it below. */
852 1.8 christos environ = (char**) env;
853 1.8 christos if ((flags & PEX_SEARCH) != 0)
854 1.8 christos {
855 1.8 christos execvp (executable, to_ptr32 (argv));
856 1.8 christos failed.fn = "execvp", failed.err = errno;
857 1.8 christos }
858 1.8 christos else
859 1.8 christos {
860 1.8 christos execv (executable, to_ptr32 (argv));
861 1.8 christos failed.fn = "execv", failed.err = errno;
862 1.8 christos }
863 1.8 christos }
864 1.8 christos
865 1.8 christos /* Something failed, report an error. We don't use stdio
866 1.8 christos routines, because we might be here due to a vfork call. */
867 1.8 christos ssize_t retval = 0;
868 1.8 christos
869 1.8 christos if (!do_pipe
870 1.8 christos || write (pipes[1], &failed, sizeof (failed)) != sizeof (failed))
871 1.8 christos {
872 1.8 christos /* The parent will not see our scream above, so write to
873 1.8 christos stdout. */
874 1.8 christos #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
875 1.8 christos writeerr (obj->pname);
876 1.8 christos writeerr (": error trying to exec '");
877 1.8 christos writeerr (executable);
878 1.8 christos writeerr ("': ");
879 1.8 christos writeerr (failed.fn);
880 1.8 christos writeerr (": ");
881 1.8 christos writeerr (xstrerror (failed.err));
882 1.8 christos writeerr ("\n");
883 1.8 christos #undef writeerr
884 1.8 christos }
885 1.1 christos
886 1.8 christos /* Exit with -2 if the error output failed, too. */
887 1.8 christos _exit (retval < 0 ? -2 : -1);
888 1.8 christos }
889 1.1 christos /* NOTREACHED */
890 1.1 christos return (pid_t) -1;
891 1.1 christos
892 1.1 christos default:
893 1.1 christos /* Parent process. */
894 1.8 christos {
895 1.8 christos /* Restore environ. Note that the parent either doesn't run
896 1.8 christos until the child execs/exits (standard vfork behaviour), or
897 1.8 christos if it does run then vfork is behaving more like fork. In
898 1.8 christos either case we needn't worry about clobbering the child's
899 1.8 christos copy of environ. */
900 1.8 christos environ = save_environ;
901 1.8 christos
902 1.8 christos struct fn_err failed;
903 1.8 christos failed.fn = NULL;
904 1.8 christos if (do_pipe)
905 1.8 christos {
906 1.8 christos close (pipes[1]);
907 1.8 christos ssize_t len = read (pipes[0], &failed, sizeof (failed));
908 1.8 christos if (len < 0)
909 1.8 christos failed.fn = NULL;
910 1.8 christos close (pipes[0]);
911 1.8 christos }
912 1.1 christos
913 1.8 christos if (!failed.fn && in != STDIN_FILE_NO)
914 1.1 christos if (close (in) < 0)
915 1.8 christos failed.fn = "close", failed.err = errno;
916 1.8 christos if (!failed.fn && out != STDOUT_FILE_NO)
917 1.1 christos if (close (out) < 0)
918 1.8 christos failed.fn = "close", failed.err = errno;
919 1.8 christos if (!failed.fn && errdes != STDERR_FILE_NO)
920 1.1 christos if (close (errdes) < 0)
921 1.8 christos failed.fn = "close", failed.err = errno;
922 1.1 christos
923 1.8 christos if (failed.fn)
924 1.8 christos {
925 1.8 christos *err = failed.err;
926 1.8 christos *errmsg = failed.fn;
927 1.8 christos return (pid_t) -1;
928 1.8 christos }
929 1.8 christos }
930 1.1 christos return pid;
931 1.1 christos }
932 1.1 christos }
933 1.1 christos #endif /* SPAWN */
934 1.1 christos
935 1.1 christos /* Wait for a child process to complete. */
936 1.1 christos
937 1.11 christos static pid_t
938 1.1 christos pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
939 1.1 christos struct pex_time *time, int done, const char **errmsg,
940 1.1 christos int *err)
941 1.1 christos {
942 1.1 christos /* If we are cleaning up when the caller didn't retrieve process
943 1.1 christos status for some reason, encourage the process to go away. */
944 1.1 christos if (done)
945 1.1 christos kill (pid, SIGTERM);
946 1.1 christos
947 1.1 christos if (pex_wait (obj, pid, status, time) < 0)
948 1.1 christos {
949 1.1 christos *err = errno;
950 1.1 christos *errmsg = "wait";
951 1.1 christos return -1;
952 1.1 christos }
953 1.1 christos
954 1.1 christos return 0;
955 1.1 christos }
956 1.1 christos
957 1.1 christos /* Create a pipe. */
958 1.1 christos
959 1.1 christos static int
960 1.1 christos pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
961 1.1 christos int binary ATTRIBUTE_UNUSED)
962 1.1 christos {
963 1.1 christos return pipe (p);
964 1.1 christos }
965 1.1 christos
966 1.1 christos /* Get a FILE pointer to read from a file descriptor. */
967 1.1 christos
968 1.1 christos static FILE *
969 1.1 christos pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
970 1.1 christos int binary ATTRIBUTE_UNUSED)
971 1.1 christos {
972 1.1 christos return fdopen (fd, "r");
973 1.1 christos }
974 1.1 christos
975 1.1 christos static FILE *
976 1.1 christos pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
977 1.1 christos int binary ATTRIBUTE_UNUSED)
978 1.1 christos {
979 1.1 christos if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
980 1.1 christos return NULL;
981 1.1 christos return fdopen (fd, "w");
982 1.1 christos }
983 1.1 christos
984 1.1 christos static void
985 1.1 christos pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
986 1.1 christos {
987 1.1 christos #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
988 1.1 christos while (obj->sysdep != NULL)
989 1.1 christos {
990 1.1 christos struct status_list *this;
991 1.1 christos struct status_list *next;
992 1.1 christos
993 1.1 christos this = (struct status_list *) obj->sysdep;
994 1.1 christos next = this->next;
995 1.1 christos free (this);
996 1.1 christos obj->sysdep = (void *) next;
997 1.1 christos }
998 1.1 christos #endif
999 1.1 christos }
1000