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