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