Coverage Report

Created: 2024-05-21 06:29

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