diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 27280a3274d966fac46e1f9d99f00ffb83f3b6ff..727b98761761302d56bcb3fbd97ae3da2d3811af 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,5 +1,15 @@
 2006-08-27  Ian Lance Taylor  <ian@airs.com>
 
+	PR driver/27622
+	* pex-common.h (struct pex_funcs): Add toclose parameter to
+	exec_child field.
+	* pex-common.c (pex_run_in_environment): Pass toclose to
+	exec_child.
+	* pex-djgpp.c (pex_djgpp_exec_child): Add toclose parameter.
+	* pex-unix.c (pex_unix_exec_child): Likewise.
+	* pex-msdos.c (pex_msdos_exec_child): Likewise.
+	* pex-win32.c (pex_win32_exec_child): Likewise.
+
 	PR other/28797
 	* cp-demangle.c (d_pointer_to_member_type): Do add a substitution
 	for a qualified member which is not a function.
diff --git a/libiberty/pex-common.c b/libiberty/pex-common.c
index 3daa638d402b4521a2d416f4a5ea76a85cc1c9ef..bb127f2ed77f7853e7a791e86191e9780135beae 100644
--- a/libiberty/pex-common.c
+++ b/libiberty/pex-common.c
@@ -157,6 +157,7 @@ pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
   char *outname;
   int outname_allocated;
   int p[2];
+  int toclose;
   long pid;
 
   in = -1;
@@ -297,10 +298,18 @@ pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
 	}
     }
 
+  /* If we are using pipes, the child process has to close the next
+     input pipe.  */
+
+  if ((obj->flags & PEX_USE_PIPES) == 0)
+    toclose = -1;
+  else
+    toclose = obj->next_input;
+
   /* Run the program.  */
 
   pid = obj->funcs->exec_child (obj, flags, executable, argv, env,
-                                in, out, errdes, &errmsg, err);
+				in, out, errdes, toclose, &errmsg, err);
   if (pid < 0)
     goto error_exit;
 
diff --git a/libiberty/pex-common.h b/libiberty/pex-common.h
index 520f26a260df5702a4c0d8bb29573fedae4ff3c1..0e88c355ffc1abd80e97c4617fd6e216e0629582 100644
--- a/libiberty/pex-common.h
+++ b/libiberty/pex-common.h
@@ -96,17 +96,20 @@ struct pex_funcs
   int (*open_write) (struct pex_obj *, const char */* name */,
                      int /* binary */);
   /* Execute a child process.  FLAGS, EXECUTABLE, ARGV, ERR are from
-     pex_run.  IN, OUT, ERRDES are each a descriptor, from open_read,
-     open_write, or pipe, or they are one of STDIN_FILE_NO,
-     STDOUT_FILE_NO or STDERR_FILE_NO; if not STD*_FILE_NO, they
-     should be closed.  The function should handle the
+     pex_run.  IN, OUT, ERRDES, TOCLOSE are all descriptors, from
+     open_read, open_write, or pipe, or they are one of STDIN_FILE_NO,
+     STDOUT_FILE_NO or STDERR_FILE_NO; if IN, OUT, and ERRDES are not
+     STD*_FILE_NO, they should be closed.  If the descriptor TOCLOSE
+     is not -1, and the system supports pipes, TOCLOSE should be
+     closed in the child process.  The function should handle the
      PEX_STDERR_TO_STDOUT flag.  Return >= 0 on success, or -1 on
      error and set *ERRMSG and *ERR.  */
   long (*exec_child) (struct pex_obj *, int /* flags */,
                       const char */* executable */, char * const * /* argv */,
                       char * const * /* env */,
                       int /* in */, int /* out */, int /* errdes */,
-		      const char **/* errmsg */, int */* err */);
+		      int /* toclose */, const char **/* errmsg */,
+		      int */* err */);
   /* Close a descriptor.  Return 0 on success, -1 on error.  */
   int (*close) (struct pex_obj *, int);
   /* Wait for a child to complete, returning exit status in *STATUS
diff --git a/libiberty/pex-djgpp.c b/libiberty/pex-djgpp.c
index acaa4c43fdbbe555f7d026c7993a4dc7263afe39..ac5a4f97ba76a33681bb6aef991f3a1d20aecb5e 100644
--- a/libiberty/pex-djgpp.c
+++ b/libiberty/pex-djgpp.c
@@ -46,7 +46,7 @@ static int pex_djgpp_open_read (struct pex_obj *, const char *, int);
 static int pex_djgpp_open_write (struct pex_obj *, const char *, int);
 static long pex_djgpp_exec_child (struct pex_obj *, int, const char *,
 				  char * const *, char * const *,
-                                  int, int, int,
+				  int, int, int, int,
 				  const char **, int *);
 static int pex_djgpp_close (struct pex_obj *, int);
 static int pex_djgpp_wait (struct pex_obj *, long, int *, struct pex_time *,
@@ -114,7 +114,8 @@ static long
 pex_djgpp_exec_child (struct pex_obj *obj, int flags, const char *executable,
 		      char * const * argv, char * const * env,
                       int in, int out, int errdes,
-		      const char **errmsg, int *err)
+		      int toclose ATTRIBUTE_UNUSED, const char **errmsg,
+		      int *err)
 {
   int org_in, org_out, org_errdes;
   int status;
diff --git a/libiberty/pex-msdos.c b/libiberty/pex-msdos.c
index bcad93dbe263b3957dd2121d954fd2a5ac47e82e..b5acd86b0f5febf4c2ba6fc314d665d6631f03bb 100644
--- a/libiberty/pex-msdos.c
+++ b/libiberty/pex-msdos.c
@@ -56,7 +56,8 @@ static int pex_msdos_open (struct pex_obj *, const char *, int);
 static int pex_msdos_fdindex (struct pex_msdos *, int);
 static long pex_msdos_exec_child (struct pex_obj *, int, const char *,
 				  char * const *, char * const *,
-                                  int, int, int, const char **, int *);
+				  int, int, int, int,
+				  int, const char **, int *);
 static int pex_msdos_close (struct pex_obj *, int);
 static int pex_msdos_wait (struct pex_obj *, long, int *, struct pex_time *,
 			   int, const char **, int *);
@@ -154,6 +155,7 @@ pex_msdos_close (struct pex_obj *obj, int fd)
 static long
 pex_msdos_exec_child (struct pex_obj *obj, int flags, const char *executable,
 		      char * const * argv, char * const * env, int in, int out,
+		      int toclose ATTRIBUTE_UNUSED,
 		      int errdes ATTRIBUTE_UNUSED, const char **errmsg,
 		      int *err)
 {
diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c
index e006e5992978b67591ff990c07ba57e15dad0f63..c5fa984817e7582a5fd6dc6dc5326ffe9eaf6495 100644
--- a/libiberty/pex-unix.c
+++ b/libiberty/pex-unix.c
@@ -271,7 +271,8 @@ static int pex_unix_open_read (struct pex_obj *, const char *, int);
 static int pex_unix_open_write (struct pex_obj *, const char *, int);
 static long pex_unix_exec_child (struct pex_obj *, int, const char *,
 				 char * const *, char * const *,
-                                 int, int, int, const char **, int *);
+				 int, int, int, int,
+				 const char **, int *);
 static int pex_unix_close (struct pex_obj *, int);
 static int pex_unix_wait (struct pex_obj *, long, int *, struct pex_time *,
 			  int, const char **, int *);
@@ -358,7 +359,7 @@ static long
 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
 		     char * const * argv, char * const * env,
                      int in, int out, int errdes,
-		     const char **errmsg, int *err)
+		     int toclose, const char **errmsg, int *err)
 {
   pid_t pid;
 
@@ -408,6 +409,11 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
 	  if (close (errdes) < 0)
 	    pex_child_error (obj, executable, "close", errno);
 	}
+      if (toclose >= 0)
+	{
+	  if (close (toclose) < 0)
+	    pex_child_error (obj, executable, "close", errno);
+	}
       if ((flags & PEX_STDERR_TO_STDOUT) != 0)
 	{
 	  if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
diff --git a/libiberty/pex-win32.c b/libiberty/pex-win32.c
index 45725457b6af76ffb5060c93a13300a1114353b4..aef386d3cc2e0e868c5cdd9ef9aa6730a8cdb4ac 100644
--- a/libiberty/pex-win32.c
+++ b/libiberty/pex-win32.c
@@ -81,7 +81,7 @@ static int pex_win32_open_read (struct pex_obj *, const char *, int);
 static int pex_win32_open_write (struct pex_obj *, const char *, int);
 static long pex_win32_exec_child (struct pex_obj *, int, const char *,
 				  char * const *, char * const *,
-                                  int, int, int,
+                                  int, int, int, int,
 				  const char **, int *);
 static int pex_win32_close (struct pex_obj *, int);
 static int pex_win32_wait (struct pex_obj *, long, int *,
@@ -699,7 +699,9 @@ static long
 pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags,
 		      const char *executable, char * const * argv,
                       char* const* env,
-		      int in, int out, int errdes, const char **errmsg,
+		      int in, int out, int errdes,
+		      int toclose ATTRIBUTE_UNUSED,
+		      const char **errmsg,
 		      int *err)
 {
   long pid;