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