This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH RFC: Remove fork from collect2


Here is the promised patch to remove the fork call from collect2.

collect2 is using fork to implement, essentially, popen.  The actual
popen call is generally considered to be unreliable on a Unix system
because it invokes a shell, and is thus vulnerable to all sorts of
environment variables and quoting issues.  So this patch creates a new
function pex_read() which implements a safe version of popen.

However, I don't have access to the various non-Unix systems which we
need to support.  For the existing pexecute() function, we have
support for Unix, DJGPP, MPW, MSDOS, OS/2, and Win32.

So what I did for pex_read() is to implement a Unix version, and then
I implemented a generic version which simply calls popen.  This is
based on the theory that all of those platforms will implement popen,
which I expect is true except possibly for MSDOS.  Ideally, of course,
somebody with access to one of the systems in question will write a
version which is designed for that system.

This patch doesn't yet have docs and ChangeLog entries.  Also the code
needs to be cleaned up a little bit, and it needs some more testing.

I'd like to see whether anybody objects to this approach before I
propose checking it in.

(I created pexecute.h because I need to include <stdio.h> in order to
declare pex_read, but adding an include of <stdio.h> to libiberty.h
breaks the compilation of libiberty/strerror.c on GNU/Linux.)

Ian

Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.99
diff -p -u -r1.99 Makefile.in
--- libiberty/Makefile.in	22 Jan 2004 19:10:56 -0000	1.99
+++ libiberty/Makefile.in	17 Mar 2004 02:25:01 -0000
@@ -129,7 +129,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS)
 CFILES = alloca.c argv.c asprintf.c atexit.c				\
 	basename.c bcmp.c bcopy.c bsearch.c bzero.c			\
 	calloc.c choose-temp.c clock.c concat.c cp-demangle.c		\
-	 cp-demint.c cplus-dem.c					\
+	cp-demint.c cplus-dem.c						\
 	dyn-string.c							\
 	fdmatch.c ffs.c fibheap.c floatformat.c fnmatch.c		\
 	getcwd.c getopt.c getopt1.c getpagesize.c getpwd.c getruntime.c	\
@@ -139,17 +139,18 @@ CFILES = alloca.c argv.c asprintf.c atex
 	lrealpath.c							\
 	make-relative-prefix.c						\
 	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
-	 mempcpy.c memset.c mkstemps.c					\
+	mempcpy.c memset.c mkstemps.c					\
 	objalloc.c obstack.c						\
 	partition.c							\
-	 pex-djgpp.c pex-mpw.c pex-msdos.c pex-os2.c			\
-	 pex-unix.c pex-win32.c						\
-         physmem.c putenv.c						\
+	pex-djgpp.c pex-mpw.c pex-msdos.c pex-os2.c			\
+	pex-unix.c pex-win32.c						\
+	pexrd-unix.c pexrd-generic.					\
+        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	\
-	 strerror.c strncasecmp.c strncmp.c strrchr.c strsignal.c	\
-	 strstr.c strtod.c strtol.c strtoul.c				\
+	splay-tree.c stpcpy.c stpncpy.c strcasecmp.c strchr.c strdup.c	\
+	strerror.c strncasecmp.c strncmp.c strrchr.c strsignal.c	\
+	strstr.c strtod.c strtol.c strtoul.c				\
 	ternary.c tmpnam.c						\
 	vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c	\
 	waitpid.c							\
@@ -157,44 +158,51 @@ CFILES = alloca.c argv.c asprintf.c atex
 
 # These are always included in the library.  The first four are listed
 # first and by compile time to optimize parallel builds.
-REQUIRED_OFILES = ./regex.o ./cplus-dem.o ./cp-demangle.o ./cp-demint.o ./md5.o		\
-	./alloca.o ./argv.o							\
-	./choose-temp.o ./concat.o						\
+REQUIRED_OFILES = ./regex.o ./cplus-dem.o ./cp-demangle.o		\
+	./cp-demint.o ./md5.o						\
+	./alloca.o ./argv.o						\
+	./choose-temp.o ./concat.o					\
 	./dyn-string.o							\
-	./fdmatch.o ./fibheap.o ./floatformat.o ./fnmatch.o			\
-	./getopt.o ./getopt1.o ./getpwd.o ./getruntime.o			\
-	./hashtab.o ./hex.o							\
+	./fdmatch.o ./fibheap.o ./floatformat.o ./fnmatch.o		\
+	./getopt.o ./getopt1.o ./getpwd.o ./getruntime.o		\
+	./hashtab.o ./hex.o						\
 	./lbasename.o							\
 	./lrealpath.o							\
-	./make-relative-prefix.o						\
+	./make-relative-prefix.o					\
 	./make-temp-file.o						\
-	./objalloc.o ./obstack.o						\
-	./partition.o ./physmem.o @pexecute@						\
-	./safe-ctype.o ./sort.o ./spaces.o ./splay-tree.o ./strerror.o		\
+	./objalloc.o ./obstack.o					\
+	./partition.o ./physmem.o @pexecute@				\
+	./safe-ctype.o ./sort.o ./spaces.o ./splay-tree.o ./strerror.o	\
 	 ./strsignal.o							\
 	./ternary.o							\
-	./xatexit.o ./xexit.o ./xmalloc.o ./xmemdup.o ./xstrdup.o ./xstrerror.o
+	./xatexit.o ./xexit.o ./xmalloc.o ./xmemdup.o ./xstrdup.o	\
+	./xstrerror.o
 
 # These are all the objects that configure may add to the library via
 # $funcs or EXTRA_OFILES.  This list exists here only for "make
 # maint-missing" and "make check".
-CONFIGURED_OFILES = ./asprintf.o ./atexit.o					\
-	./basename.o ./bcmp.o ./bcopy.o ./bsearch.o ./bzero.o			\
-	./calloc.o ./clock.o ./copysign.o					\
+CONFIGURED_OFILES = ./asprintf.o ./atexit.o				\
+	./basename.o ./bcmp.o ./bcopy.o ./bsearch.o ./bzero.o		\
+	./calloc.o ./clock.o ./copysign.o				\
 	./_doprnt.o							\
 	./ffs.o								\
-	./getcwd.o ./getpagesize.o						\
+	./getcwd.o ./getpagesize.o					\
 	./index.o ./insque.o						\
-	./memchr.o ./memcmp.o ./memcpy.o ./memmove.o ./mempcpy.o ./memset.o ./mkstemps.o \
-	./pex-djgpp.o ./pex-mpw.o ./pex-msdos.o ./pex-os2.o			\
-	 ./pex-unix.o ./pex-win32.o						\
-	 ./putenv.o							\
-	./random.o ./rename.o ./rindex.o					\
-	./setenv.o ./sigsetmask.o ./snprintf.o ./stpcpy.o ./stpncpy.o ./strcasecmp.o \
-	 ./strchr.o ./strdup.o ./strncasecmp.o ./strncmp.o ./strrchr.o ./strstr.o	\
-	 ./strtod.o ./strtol.o ./strtoul.o					\
+	./memchr.o ./memcmp.o ./memcpy.o ./memmove.o ./mempcpy.o	\
+	./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 ./strcasecmp.o					\
+	./strchr.o ./strdup.o ./strncasecmp.o ./strncmp.o		\
+	./strrchr.o ./strstr.o						\
+	./strtod.o ./strtol.o ./strtoul.o				\
 	./tmpnam.o							\
-	./vasprintf.o ./vfork.o ./vfprintf.o ./vprintf.o ./vsnprintf.o ./vsprintf.o	\
+	./vasprintf.o ./vfork.o ./vfprintf.o ./vprintf.o		\
+	./vsnprintf.o ./vsprintf.o					\
 	./waitpid.o
 
 # These files are installed if the library has been configured to do so.
@@ -746,14 +754,16 @@ $(CONFIGURED_OFILES): stamp-picdir
 	$(COMPILE.c) $(srcdir)/partition.c $(OUTPUT_OPTION)
 
 ./pex-djgpp.o: $(srcdir)/pex-djgpp.c config.h $(INCDIR)/ansidecl.h \
-	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
+	$(INCDIR)/pexecute.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pex-djgpp.c -o pic/$@; \
 	else true; fi
 	$(COMPILE.c) $(srcdir)/pex-djgpp.c $(OUTPUT_OPTION)
 
 ./pex-mpw.o: $(srcdir)/pex-mpw.c config.h $(INCDIR)/ansidecl.h \
-	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
+	$(INCDIR)/pexecute.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pex-mpw.c -o pic/$@; \
 	else true; fi
@@ -761,33 +771,52 @@ $(CONFIGURED_OFILES): stamp-picdir
 
 ./pex-msdos.o: $(srcdir)/pex-msdos.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
-	$(INCDIR)/safe-ctype.h
+	$(INCDIR)/pexecute.h $(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pex-msdos.c -o pic/$@; \
 	else true; fi
 	$(COMPILE.c) $(srcdir)/pex-msdos.c $(OUTPUT_OPTION)
 
 ./pex-os2.o: $(srcdir)/pex-os2.c config.h $(INCDIR)/ansidecl.h \
-	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
+	$(INCDIR)/pexecute.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pex-os2.c -o pic/$@; \
 	else true; fi
 	$(COMPILE.c) $(srcdir)/pex-os2.c $(OUTPUT_OPTION)
 
 ./pex-unix.o: $(srcdir)/pex-unix.c config.h $(INCDIR)/ansidecl.h \
-	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
+	$(INCDIR)/pexecute.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/pex-unix.c -o pic/$@; \
 	else true; fi
 	$(COMPILE.c) $(srcdir)/pex-unix.c $(OUTPUT_OPTION)
 
 ./pex-win32.o: $(srcdir)/pex-win32.c config.h $(INCDIR)/ansidecl.h \
-	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
+	$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
+	$(INCDIR)/pexecute.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(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 \
+	$(INCDIR)/pexecute.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 \
+	$(INCDIR)/pexecute.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
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -807,7 +836,8 @@ $(CONFIGURED_OFILES): stamp-picdir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/random.c $(OUTPUT_OPTION)
 
-./regex.o: $(srcdir)/regex.c config.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h
+./regex.o: $(srcdir)/regex.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/xregex.h \
+	$(INCDIR)/xregex2.h
 	if [ x"$(PICFLAG)" != x ]; then \
 	  $(COMPILE.c) $(PICFLAG) $(srcdir)/regex.c -o pic/$@; \
 	else true; fi
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	17 Mar 2004 02:25:04 -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/pex-common.h
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pex-common.h,v
retrieving revision 1.1
diff -p -u -r1.1 pex-common.h
--- libiberty/pex-common.h	24 Jan 2003 20:02:11 -0000	1.1
+++ libiberty/pex-common.h	17 Mar 2004 02:25:04 -0000
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "libiberty.h"
+#include "pexecute.h"
 
 #define install_error_msg "installation problem, cannot exec `%s'"
 
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	17 Mar 2004 02:25:04 -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	17 Mar 2004 02:25:04 -0000
@@ -0,0 +1,131 @@
+/* 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_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
+
+extern int execv ();
+extern int execvp ();
+
+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;
+     const char *temp_base ATTRIBUTE_UNUSED;
+     char **errmsg_fmt;
+     char **errmsg_arg;
+     int flags;
+     int *pidptr;
+{
+  int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
+  int pid;
+  int pdes[2];
+  int retries;
+  int sleep_interval;
+  FILE *ret;
+
+  if (pipe (pdes) < 0)
+    {
+      *errmsg_fmt = "pipe";
+      *errmsg_arg = NULL;
+      return NULL;
+    }
+
+  sleep_interval = 1;
+  pid = -1;
+  for (retries = 0; retries < 4; retries++)
+    {
+      pid = fork ();
+      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 (pdes[1] != STDOUT_FILE_NO)
+	{
+	  close (STDOUT_FILE_NO);
+	  dup (pdes[1]);
+	  close (pdes[1]);
+	}
+      close (pdes[0]);
+
+      (*func) (program, argv);
+
+      fprintf (stderr, "%s: ", this_pname);
+      fprintf (stderr, install_error_msg, program);
+      fprintf (stderr, ": %s\n", xstrerror (errno));
+      exit (-1);
+      /* NOTREACHED */
+      return NULL;
+
+    default:
+      close (pdes[1]);
+      ret = fdopen (pdes[0], "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: 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	17 Mar 2004 02:25:05 -0000
@@ -261,23 +261,6 @@ extern void hex_init PARAMS ((void));
    the argument being performed exactly once.  */
 #define hex_value(c)	((unsigned int) _hex_value[(unsigned char) (c)])
 
-/* Definitions used by the pexecute routine.  */
-
-#define PEXECUTE_FIRST   1
-#define PEXECUTE_LAST    2
-#define PEXECUTE_ONE     (PEXECUTE_FIRST + PEXECUTE_LAST)
-#define PEXECUTE_SEARCH  4
-#define PEXECUTE_VERBOSE 8
-
-/* Execute a program.  */
-
-extern int pexecute PARAMS ((const char *, char * const *, const char *,
-			    const char *, char **, char **, int));
-
-/* Wait for pexecute to finish.  */
-
-extern int pwait PARAMS ((int, int *, int));
-
 #if !HAVE_DECL_ASPRINTF
 /* Like sprintf but provides a pointer to malloc'd storage, which must
    be freed by the caller.  */
Index: include/pexecute.h
===================================================================
RCS file: include/pexecute.h
diff -N include/pexecute.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ include/pexecute.h	17 Mar 2004 02:25:05 -0000
@@ -0,0 +1,60 @@
+/* Declarations of the pexecute functions for libiberty.
+   Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef PEXECUTE_H
+#define PEXECUTE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+#include <stdio.h>
+
+/* Definitions used by the pexecute routine.  */
+
+#define PEXECUTE_FIRST   1
+#define PEXECUTE_LAST    2
+#define PEXECUTE_ONE     (PEXECUTE_FIRST + PEXECUTE_LAST)
+#define PEXECUTE_SEARCH  4
+#define PEXECUTE_VERBOSE 8
+
+/* Execute a program.  */
+
+extern int pexecute PARAMS ((const char *, char * const *, const char *,
+			    const char *, char **, char **, int));
+
+/* 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));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! defined (PEXECUTE_H) */
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	17 Mar 2004 02:25:05 -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.  */
 
@@ -1518,7 +1528,6 @@ collect_execute (const char *prog, char 
 
       fprintf (stderr, "\n");
     }
-
   fflush (stdout);
   fflush (stderr);
 
@@ -1994,9 +2003,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 +2022,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 +2037,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 +2119,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 +2143,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 +2181,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 +2192,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 +2228,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: gcc/system.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/system.h,v
retrieving revision 1.207
diff -p -u -r1.207 system.h
--- gcc/system.h	12 Mar 2004 10:03:27 -0000	1.207
+++ gcc/system.h	17 Mar 2004 02:25:10 -0000
@@ -478,6 +478,7 @@ extern int snprintf (char *, size_t, con
 
 /* Get libiberty declarations.  */
 #include "libiberty.h"
+#include "pexecute.h"
 
 /* Provide a default for the HOST_BIT_BUCKET.
    This suffices for POSIX-like hosts.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]