This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH RFA: Remove vfork from collect2
- From: Ian Lance Taylor <ian at wasabisystems dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 17 Mar 2004 23:41:43 -0500
- Subject: PATCH RFA: Remove vfork from collect2
This patch changes collect2 to not call vfork. As previously
described, this patch introduces the new functions pex_read and
pex_read_close to libiberty. A unix version is provided which calls
vfork. A generic version is provided which calls popen.
I figured out the problem with including <stdio.h> in libiberty.h, and
this patch fixes that too.
OK for mainline?
Ian
gcc/ChangeLog:
2004-03-17 Ian Lance Taylor <ian@wasabisystems.com>
* collect2.c (collect_status): New static function, broken out of
collect_wait.
(collect_wait): Call collect_status.
(do_read_wait): New static function.
(scan_prog_file): Call pex_read instead of pipe and vfork.
(scan_libraries): Likewise.
include/ChangeLog:
2004-03-17 Ian Lance Taylor <ian@wasabisystems.com>
* libiberty.h: Include <stdio.h>.
(pex_read, pex_read_close): Declare.
libiberty/ChangeLog:
2004-03-17 Ian Lance Taylor <ian@wasabisystems.com>
* pexrd-unix.c: New file.
* pexrd-generic.c: New file.
* configure.ac: Add either ./pexrd-unix.o or ./pexrd-generic.o to
pexecute.
* strerror.c: Redefine sys_nerr and sys_errlist before including
ansidecl.h and libiberty.h.
* Makefile.in: Run maint-deps.
(CFILES): Add pexrd-unix.c and pexrd-generic.c.
(CONFIGURED_OFILES): Add ./pexrd-unix.o and ./pexrd-generic.o.
* pexecute.txh: Document pex_read and pex_read_close.
* configure, functions.texi: Regenerate.
Index: gcc/collect2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/collect2.c,v
retrieving revision 1.162
diff -p -u -r1.162 collect2.c
--- gcc/collect2.c 10 Mar 2004 00:17:34 -0000 1.162
+++ gcc/collect2.c 18 Mar 2004 04:12:13 -0000
@@ -35,19 +35,6 @@ Software Foundation, 59 Temple Place - S
# define SIGCHLD SIGCLD
#endif
-#ifdef vfork /* Autoconf may define this to fork for us. */
-# define VFORK_STRING "fork"
-#else
-# define VFORK_STRING "vfork"
-#endif
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-#ifdef VMS
-#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
- lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
-#endif /* VMS */
-
#ifndef LIBRARY_PATH_ENV
#define LIBRARY_PATH_ENV "LIBRARY_PATH"
#endif
@@ -254,7 +241,9 @@ static char *find_a_file (struct path_pr
static void add_prefix (struct path_prefix *, const char *);
static void prefix_from_env (const char *, struct path_prefix *);
static void prefix_from_string (const char *, struct path_prefix *);
+static int collect_status (const char *, int status);
static void do_wait (const char *);
+static void do_read_wait (const char *, FILE *);
static void fork_execute (const char *, char **);
static void maybe_unlink (const char *);
static void add_to_list (struct head *, const char *);
@@ -1455,14 +1444,11 @@ main (int argc, char **argv)
}
-/* Wait for a process to finish, and exit if a nonzero status is found. */
+/* Handle error status returned by a finished process. */
-int
-collect_wait (const char *prog)
+static int
+collect_status (const char *prog, int status)
{
- int status;
-
- pwait (pid, &status, 0);
if (status)
{
if (WIFSIGNALED (status))
@@ -1480,6 +1466,17 @@ collect_wait (const char *prog)
return 0;
}
+/* Wait for a process to finish, and exit if a nonzero status is found. */
+
+int
+collect_wait (const char *prog)
+{
+ int status;
+
+ pwait (pid, &status, 0);
+ return collect_status (prog, status);
+}
+
static void
do_wait (const char *prog)
{
@@ -1491,6 +1488,19 @@ do_wait (const char *prog)
}
}
+static void
+do_read_wait (const char *prog, FILE *inf)
+{
+ int status;
+
+ pex_read_close (pid, inf, &status, 0);
+ status = collect_status (prog, status);
+ if (status != 0)
+ {
+ error ("%s returned %d exit status", prog, status);
+ collect_exit (status);
+ }
+}
/* Execute a program, and wait for the reply. */
@@ -1994,9 +2004,10 @@ scan_prog_file (const char *prog_name, e
char *real_nm_argv[4];
const char **nm_argv = (const char **) real_nm_argv;
int argc = 0;
- int pipe_fd[2];
char *p, buf[1024];
FILE *inf;
+ char *errmsg_fmt;
+ char *errmsg_arg;
if (which_pass == PASS_SECOND)
return;
@@ -2012,13 +2023,6 @@ scan_prog_file (const char *prog_name, e
nm_argv[argc++] = prog_name;
nm_argv[argc++] = (char *) 0;
- if (pipe (pipe_fd) < 0)
- fatal_perror ("pipe");
-
- inf = fdopen (pipe_fd[0], "r");
- if (inf == (FILE *) 0)
- fatal_perror ("fdopen");
-
/* Trace if needed. */
if (vflag)
{
@@ -2034,36 +2038,16 @@ scan_prog_file (const char *prog_name, e
fflush (stdout);
fflush (stderr);
- /* Spawn child nm on pipe. */
- pid = vfork ();
- if (pid == -1)
- fatal_perror (VFORK_STRING);
-
- if (pid == 0) /* child context */
- {
- /* setup stdout */
- if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 %d 1", pipe_fd[1]);
-
- if (close (pipe_fd[0]) < 0)
- fatal_perror ("close %d", pipe_fd[0]);
-
- if (close (pipe_fd[1]) < 0)
- fatal_perror ("close %d", pipe_fd[1]);
-
- execv (nm_file_name, real_nm_argv);
- fatal_perror ("execv %s", nm_file_name);
- }
+ inf = pex_read (nm_file_name, real_nm_argv, nm_file_name, NULL,
+ &errmsg_fmt, &errmsg_arg, 0, &pid);
+ if (inf == (FILE *) 0)
+ fatal_perror (errmsg_fmt, errmsg_arg);
- /* Parent context from here on. */
int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif
- if (close (pipe_fd[1]) < 0)
- fatal_perror ("close %d", pipe_fd[1]);
-
if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
@@ -2136,10 +2120,7 @@ scan_prog_file (const char *prog_name, e
if (debug)
fprintf (stderr, "\n");
- if (fclose (inf) != 0)
- fatal_perror ("fclose");
-
- do_wait (nm_file_name);
+ do_read_wait (nm_file_name, inf);
signal (SIGINT, int_handler);
#ifdef SIGQUIT
@@ -2163,9 +2144,10 @@ scan_libraries (const char *prog_name)
char *real_ldd_argv[4];
const char **ldd_argv = (const char **) real_ldd_argv;
int argc = 0;
- int pipe_fd[2];
char buf[1024];
FILE *inf;
+ char *errmsg_fmt;
+ char *errmsg_arg;
/* If we do not have an `ldd', complain. */
if (ldd_file_name == 0)
@@ -2200,26 +2182,10 @@ scan_libraries (const char *prog_name)
fflush (stdout);
fflush (stderr);
- /* Spawn child ldd on pipe. */
- pid = vfork ();
- if (pid == -1)
- fatal_perror (VFORK_STRING);
-
- if (pid == 0) /* child context */
- {
- /* setup stdout */
- if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 %d 1", pipe_fd[1]);
-
- if (close (pipe_fd[0]) < 0)
- fatal_perror ("close %d", pipe_fd[0]);
-
- if (close (pipe_fd[1]) < 0)
- fatal_perror ("close %d", pipe_fd[1]);
-
- execv (ldd_file_name, real_ldd_argv);
- fatal_perror ("execv %s", ldd_file_name);
- }
+ inf = pex_read (ldd_file_name, real_ldd_argv, ldd_file_name, NULL,
+ &errmsg_fmt, &errmsg_arg, 0, &pid);
+ if (inf == (FILE *) 0)
+ fatal_perror (errmsg_fmt, errmsg_arg);
/* Parent context from here on. */
int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
@@ -2227,9 +2193,6 @@ scan_libraries (const char *prog_name)
quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif
- if (close (pipe_fd[1]) < 0)
- fatal_perror ("close %d", pipe_fd[1]);
-
if (debug)
notice ("\nldd output with constructors/destructors.\n");
@@ -2266,10 +2229,7 @@ scan_libraries (const char *prog_name)
if (debug)
fprintf (stderr, "\n");
- if (fclose (inf) != 0)
- fatal_perror ("fclose");
-
- do_wait (ldd_file_name);
+ do_read_wait (ldd_file_name, inf);
signal (SIGINT, int_handler);
#ifdef SIGQUIT
Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.100
diff -p -u -r1.100 Makefile.in
--- libiberty/Makefile.in 18 Mar 2004 01:40:15 -0000 1.100
+++ libiberty/Makefile.in 18 Mar 2004 04:12:14 -0000
@@ -144,7 +144,8 @@ CFILES = alloca.c argv.c asprintf.c atex
partition.c \
pex-djgpp.c pex-mpw.c pex-msdos.c pex-os2.c \
pex-unix.c pex-win32.c \
- physmem.c putenv.c \
+ pexrd-unix.c pexrd-generic.c \
+ physmem.c putenv.c \
random.c regex.c rename.c rindex.c \
safe-ctype.c setenv.c sigsetmask.c snprintf.c sort.c spaces.c \
splay-tree.c stpcpy.c stpncpy.c strcasecmp.c strchr.c strdup.c \
@@ -188,6 +189,7 @@ CONFIGURED_OFILES = ./asprintf.o ./atexi
./memset.o ./mkstemps.o \
./pex-djgpp.o ./pex-mpw.o ./pex-msdos.o ./pex-os2.o \
./pex-unix.o ./pex-win32.o \
+ ./pexrd-unix.o ./pexrd-generic.o \
./putenv.o \
./random.o ./rename.o ./rindex.o \
./setenv.o ./sigsetmask.o ./snprintf.o ./stpcpy.o ./stpncpy.o \
@@ -789,6 +791,20 @@ $(CONFIGURED_OFILES): stamp-picdir
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-win32.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-win32.c $(OUTPUT_OPTION)
+
+./pexrd-generic.o: $(srcdir)/pexrd-generic.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+ if [ x"$(PICFLAG)" != x ]; then \
+ $(COMPILE.c) $(PICFLAG) $(srcdir)/pexrd-generic.c -o pic/$@; \
+ else true; fi
+ $(COMPILE.c) $(srcdir)/pexrd-generic.c $(OUTPUT_OPTION)
+
+./pexrd-unix.o: $(srcdir)/pexrd-unix.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+ if [ x"$(PICFLAG)" != x ]; then \
+ $(COMPILE.c) $(PICFLAG) $(srcdir)/pexrd-unix.c -o pic/$@; \
+ else true; fi
+ $(COMPILE.c) $(srcdir)/pexrd-unix.c $(OUTPUT_OPTION)
./physmem.o: $(srcdir)/physmem.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
Index: libiberty/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/configure.ac,v
retrieving revision 1.4
diff -p -u -r1.4 configure.ac
--- libiberty/configure.ac 9 Mar 2004 23:02:47 -0000 1.4
+++ libiberty/configure.ac 18 Mar 2004 04:12:15 -0000
@@ -478,11 +478,11 @@ fi
# Figure out which version of pexecute to use.
case "${host}" in
- *-*-mingw* | *-*-winnt*) pexecute=./pex-win32.o ;;
- *-*-msdosdjgpp*) pexecute=./pex-djgpp.o ;;
- *-*-msdos*) pexecute=./pex-msdos.o ;;
- *-*-os2-emx*) pexecute=./pex-os2.o ;;
- *) pexecute=./pex-unix.o ;;
+ *-*-mingw* | *-*-winnt*) pexecute="./pex-win32.o ./pexrd-generic.o" ;;
+ *-*-msdosdjgpp*) pexecute="./pex-djgpp.o ./pexrd-generic.o" ;;
+ *-*-msdos*) pexecute="./pex-msdos.o ./pexrd-generic.o" ;;
+ *-*-os2-emx*) pexecute="./pex-os2.o ./pexrd-generic.o" ;;
+ *) pexecute="./pex-unix.o ./pexrd-unix.o" ;;
esac
AC_SUBST(pexecute)
Index: libiberty/pexecute.txh
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pexecute.txh,v
retrieving revision 1.1
diff -p -u -r1.1 pexecute.txh
--- libiberty/pexecute.txh 24 Jan 2003 20:02:11 -0000 1.1
+++ libiberty/pexecute.txh 18 Mar 2004 04:12:16 -0000
@@ -1,4 +1,4 @@
-@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags)
+@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int @var{flags})
Executes a program.
@@ -61,3 +61,39 @@ pfinish: finish generation of script
pfinish is necessary for systems like MPW where a script is generated
that runs the requested programs.
+
+@end undocumented
+
+@deftypefn Extension FILE* pex_read (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int @var{flags}, int *@var{pidptr})
+
+Executes a program and returns a stdio file for the program's standard
+output. This is a safe version of the usual Unix function
+@code{popen}.
+
+The first seven parameters are the same as for @code{pexecute}. The
+last parameter returns a process identifier to be passed to
+@code{pex_read_close}.
+
+The only flags used for the @var{flags} parameter is
+@code{PEXECUTE_SEARCH}.
+
+Upon failure, @var{errmsg_fmt} and @var{errmsg_arg} are set to the
+text of the error message with an optional argument (if not needed,
+@var{errmsg_arg} is set to @code{NULL}), and @code{NULL} is returned.
+@code{errno} is available to the caller to use.
+
+@end deftypefn
+
+@deftypefn Extension int pex_read_close (int @var{pid}, FILE *@var{file}, int *@var{status}, int @var{flags})
+
+Close a file opened by @code{pex_read}, and wait for the subprocess to
+complete. The @var{pid} and @var{file} arguments should have been
+obtained from a call to @code{pex_read}.
+
+The result is the pid of the child reaped, or -1 for failure
+(@code{errno} says why).
+
+On a successful return, *@var{status} is set to the exit status of the
+subprocess.
+
+@end deftypefn
Index: libiberty/pexrd-generic.c
===================================================================
RCS file: libiberty/pexrd-generic.c
diff -N libiberty/pexrd-generic.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libiberty/pexrd-generic.c 18 Mar 2004 04:12:16 -0000
@@ -0,0 +1,72 @@
+/* Execute a program and read stdout. Generic version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "pex-common.h"
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+FILE *
+pex_read (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags,
+ pidptr)
+ const char *program;
+ char * const *argv;
+ const char *this_pname ATTRIBUTE_UNUSED;
+ const char *temp_base ATTRIBUTE_UNUSED;
+ char **errmsg_fmt;
+ char **errmsg_arg;
+ int flags ATTRIBUTE_UNUSED;
+ int *pidptr ATTRIBUTE_UNUSED;
+{
+ char *cmd;
+ int i;
+ FILE *ret;
+
+ cmd = xstrdup (program);
+ for (i = 0; argv[i] != NULL; ++i)
+ cmd = reconcat (cmd, cmd, " ", argv[i], NULL);
+
+ ret = popen (cmd, "r");
+ if (ret == NULL)
+ {
+ *errmsg_fmt = "popen";
+ *errmsg_arg = NULL;
+ }
+
+ free (cmd);
+
+ return ret;
+}
+
+int
+pex_read_close (pid, file, status, flags)
+ int pid ATTRIBUTE_UNUSED;
+ FILE *file;
+ int *status;
+ int flags ATTRIBUTE_UNUSED;
+{
+ *status = pclose (file);
+ return 0;
+}
Index: libiberty/pexrd-unix.c
===================================================================
RCS file: libiberty/pexrd-unix.c
diff -N libiberty/pexrd-unix.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libiberty/pexrd-unix.c 18 Mar 2004 04:12:16 -0000
@@ -0,0 +1,164 @@
+/* Execute a program and read stdout. Generic Unix version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "pex-common.h"
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifndef HAVE_WAITPID
+#define waitpid(pid, status, flags) wait(status)
+#endif
+
+#ifdef vfork /* Autoconf may define this to fork for us. */
+# define VFORK_STRING "fork"
+#else
+# define VFORK_STRING "vfork"
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+#ifdef VMS
+#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
+ lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
+#endif /* VMS */
+
+/* A safe version of popen. See pex-unix.c for notes on vfork. */
+
+FILE *
+pex_read (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg,
+ flagsarg, pidptr)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base ATTRIBUTE_UNUSED;
+ char **errmsg_fmt;
+ char **errmsg_arg;
+ int flagsarg;
+ int *pidptr;
+{
+ int flags;
+ int pid;
+ int pdes[2];
+ int in;
+ int out;
+ FILE *ret;
+ /* We declare these to be volatile to avoid warnings from gcc about
+ them being clobbered by vfork. */
+ volatile int retries;
+ volatile int sleep_interval;
+
+ flags = flagsarg;
+
+ if (pipe (pdes) < 0)
+ {
+ *errmsg_fmt = "pipe";
+ *errmsg_arg = NULL;
+ return NULL;
+ }
+
+ in = pdes[READ_PORT];
+ out = pdes[WRITE_PORT];
+
+ sleep_interval = 1;
+ pid = -1;
+ for (retries = 0; retries < 4; retries++)
+ {
+ pid = vfork ();
+ if (pid >= 0)
+ break;
+ sleep (sleep_interval);
+ sleep_interval *= 2;
+ }
+
+ switch (pid)
+ {
+ case -1:
+ *errmsg_fmt = "fork";
+ *errmsg_arg = NULL;
+ return NULL;
+
+ case 0:
+ if (out != STDOUT_FILE_NO)
+ {
+ close (STDOUT_FILE_NO);
+ dup (out);
+ close (out);
+ }
+ close (in);
+
+ if (flags & PEXECUTE_SEARCH)
+ execvp (program, argv);
+ else
+ execv (program, argv);
+
+ /* We don't want to call fprintf after vfork. */
+#define writeerr(s) write (STDERR_FILE_NO, s, strlen (s))
+ writeerr (this_pname);
+ writeerr (": ");
+ writeerr ("installation problem, cannot exec '");
+ writeerr (program);
+ writeerr ("': ");
+ writeerr (xstrerror (errno));
+ writeerr ("\n");
+ _exit (-1);
+ /* NOTREACHED */
+ return NULL;
+
+ default:
+ close (out);
+ ret = fdopen (in, "r");
+ if (ret == NULL)
+ {
+ *errmsg_fmt = "fdopen";
+ *errmsg_arg = NULL;
+ return NULL;
+ }
+ *pidptr = pid;
+ return ret;
+ }
+ /* NOTREACHED */
+}
+
+int
+pex_read_close (pid, file, status, flags)
+ int pid;
+ FILE *file;
+ int *status;
+ int flags ATTRIBUTE_UNUSED;
+{
+ /* ??? Canonicalize STATUS value? */
+ fclose (file);
+ return waitpid (pid, status, 0);
+}
Index: libiberty/strerror.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/strerror.c,v
retrieving revision 1.12
diff -p -u -r1.12 strerror.c
--- libiberty/strerror.c 2 Oct 2003 19:06:29 -0000 1.12
+++ libiberty/strerror.c 18 Mar 2004 04:12:16 -0000
@@ -2,9 +2,6 @@
Written by Fred Fish. fnf@cygnus.com
This file is in the public domain. --Per Bothner. */
-#include "ansidecl.h"
-#include "libiberty.h"
-
#include "config.h"
#ifdef HAVE_SYS_ERRLIST
@@ -16,6 +13,9 @@
#define sys_nerr sys_nerr__
#define sys_errlist sys_errlist__
#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
#include <stdio.h>
#include <errno.h>
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.35
diff -p -u -r1.35 libiberty.h
--- include/libiberty.h 15 May 2003 19:02:12 -0000 1.35
+++ include/libiberty.h 18 Mar 2004 04:12:16 -0000
@@ -1,6 +1,6 @@
/* Function declarations for libiberty.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
Note - certain prototypes declared in this header file are for
functions whoes implementation copyright does not belong to the
@@ -41,6 +41,8 @@ extern "C" {
#include "ansidecl.h"
+#include <stdio.h>
+
#ifdef ANSI_PROTOTYPES
/* Get a definition for size_t. */
#include <stddef.h>
@@ -277,6 +279,15 @@ extern int pexecute PARAMS ((const char
/* Wait for pexecute to finish. */
extern int pwait PARAMS ((int, int *, int));
+
+/* Execute a program and read its standard output. */
+
+extern FILE *pex_read PARAMS ((const char *, char * const *, const char *,
+ const char *, char **, char **, int, int *));
+
+/* Wait for pex_read to finish. */
+
+extern int pex_read_close PARAMS ((int, FILE *, int *, int));
#if !HAVE_DECL_ASPRINTF
/* Like sprintf but provides a pointer to malloc'd storage, which must