diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index b983a18e7fb0dae2fa6dfef51e2bc9b55bf22e60..f3573b11039a9cdb5e0add248d1deed02651a6c2 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,20 @@
+2004-08-14  Paolo Bonzini  <bonzini@gnu.org>
+
+	PR other/17991
+
+	* Makefile.in (ALLOBJ, TESTOBJ, FIXOBJ): Add fixopts.o.
+	Update copyright year.
+	* fixfixes.c (main): Call initialize_opts from fixopts.c.
+	* fixincl.c (initialize): Call initialize_opts from fixopts.c,
+	do not include code for parsing options (environment vars).
+	(fix_with_system): Use a search path for applyfix, so that you
+	can run the test suite with two-process fixincludes.
+	* fixopts.c: New file.
+	* configure.ac: Add --enable-twoprocess.  Export ac_exeext
+	to config.h.  Default to --enable-twoprocess for MinGW32.
+	* config.h.in: Regenerate.
+	* configure: Regenerate.
+
 2004-10-04  Loren J. Rittle  <ljrittle@acm.org>
 
 	* tests/base/sys/cdefs.h: Update from test area.
diff --git a/fixincludes/Makefile.in b/fixincludes/Makefile.in
index 68e1e232a05683d13a0bd071399b3c2597846074..c067d84a3cc7f00dba47bc9554d6ecc1091c9294 100644
--- a/fixincludes/Makefile.in
+++ b/fixincludes/Makefile.in
@@ -1,6 +1,7 @@
 # Makefile for fixincludes.
 #
-#   Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+#   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+#   Free Software Foundation, Inc.
 
 #This file is part of fixincludes.
 
@@ -60,10 +61,10 @@ default : all
 LIBIBERTY=../libiberty/libiberty.a
 
 ALLOBJ = fixincl.o fixtests.o fixfixes.o server.o procopen.o \
-      fixlib.o
+      fixlib.o fixopts.o
 
-TESTOBJ = fixincl.o fixlib.o fixtests.o
-FIXOBJ  = fixfixes.o fixlib.o
+TESTOBJ = fixincl.o fixlib.o fixtests.o fixopts.o
+FIXOBJ  = fixfixes.o fixlib.o fixopts.o
 
 HDR = server.h fixlib.h
 FI  = fixincl@EXEEXT@
diff --git a/fixincludes/config.h.in b/fixincludes/config.h.in
index 6d22ee5bdee516b56c032f6098d925dd15d86c91..47d5173c4a252b5bb2b651a284cd50e2f407ddf4 100644
--- a/fixincludes/config.h.in
+++ b/fixincludes/config.h.in
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Defined to the executable file extension on the host system */
+#undef EXE_EXT
+
 /* Define to 1 if you have the declaration of `abort', and to 0 if you don't.
    */
 #undef HAVE_DECL_ABORT
diff --git a/fixincludes/configure b/fixincludes/configure
index 8e9f630a06faf86ec15247d4846ebfa9396bf0cd..d5da756ada828f68a5601d93fca3fe7f72f14732 100755
--- a/fixincludes/configure
+++ b/fixincludes/configure
@@ -847,6 +847,7 @@ if test -n "$ac_init_help"; then
 Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-twoprocess       Use a separate process to apply the fixes
   --enable-maintainer-mode enable make rules and dependencies not useful
                           (and sometimes confusing) to the casual installer
 
@@ -2343,19 +2344,39 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 # Choose one or two-process fix methodology.  Systems that cannot handle
 # bi-directional pipes must use the two process method.
 #
-case $host in
+# Check whether --enable-twoprocess or --disable-twoprocess was given.
+if test "${enable_twoprocess+set}" = set; then
+  enableval="$enable_twoprocess"
+  if test "x$enable_twoprocess" = yes; then
+	TARGET=twoprocess
+else
+	TARGET=oneprocess
+fi
+else
+  case $host in
 	i?86-*-msdosdjgpp* | \
+	i?86-*-mingw32* | \
 	*-*-beos* )
 		TARGET=twoprocess
+		;;
+
+	* )
+		TARGET=oneprocess
+		;;
+esac
+fi;
+
+
+if test $TARGET = twoprocess; then
 
 cat >>confdefs.h <<\_ACEOF
 #define SEPARATE_FIX_PROC 1
 _ACEOF
 
-		;;
+fi
 
+case $host in
 	vax-dec-bsd* )
-		TARGET=oneprocess
 
 cat >>confdefs.h <<\_ACEOF
 #define exit xexit
@@ -2367,13 +2388,14 @@ cat >>confdefs.h <<\_ACEOF
 _ACEOF
 
 		;;
-
-	* )
-		TARGET=oneprocess
-		;;
 esac
 
 
+cat >>confdefs.h <<_ACEOF
+#define EXE_EXT "$ac_exeext"
+_ACEOF
+
+
 # Checks for header files.
 
 ac_ext=c
diff --git a/fixincludes/configure.ac b/fixincludes/configure.ac
index e0058b116407aa3172674a13f281a93c56ada466..8499032db816210cbd5e5012c48f01c452fd1614 100644
--- a/fixincludes/configure.ac
+++ b/fixincludes/configure.ac
@@ -9,24 +9,40 @@ AC_PROG_CC
 # Choose one or two-process fix methodology.  Systems that cannot handle
 # bi-directional pipes must use the two process method.
 #
-case $host in
+AC_ARG_ENABLE([twoprocess],
+[  --enable-twoprocess       Use a separate process to apply the fixes],
+[if test "x$enable_twoprocess" = yes; then
+	TARGET=twoprocess
+else
+	TARGET=oneprocess
+fi],
+[case $host in
 	i?86-*-msdosdjgpp* | \
+	i?86-*-mingw32* | \
 	*-*-beos* )
 		TARGET=twoprocess
-		AC_DEFINE(SEPARATE_FIX_PROC, 1, [Define if testing and fixing are done by separate process])
 		;;
 
-	vax-dec-bsd* )
+	* )
 		TARGET=oneprocess
-		AC_DEFINE(exit, xexit, [Define to xexit if the host system does not support atexit])
-		AC_DEFINE(atexit, xatexit, [Define to xatexit if the host system does not support atexit])
 		;;
+esac])
+AC_SUBST(TARGET)
 
-	* )
-		TARGET=oneprocess
+if test $TARGET = twoprocess; then
+	AC_DEFINE(SEPARATE_FIX_PROC, 1,
+		  [Define if testing and fixing are done by separate process])
+fi
+
+case $host in
+	vax-dec-bsd* )
+		AC_DEFINE(exit, xexit, [Define to xexit if the host system does not support atexit])
+		AC_DEFINE(atexit, xatexit, [Define to xatexit if the host system does not support atexit])
 		;;
 esac
-AC_SUBST(TARGET)
+
+AC_DEFINE_UNQUOTED([EXE_EXT], "$ac_exeext",
+  [Defined to the executable file extension on the host system])
 
 # Checks for header files.
 AC_HEADER_STDC
diff --git a/fixincludes/fixfixes.c b/fixincludes/fixfixes.c
index 19fa27ed12109e8d8340d3e2576aef75b007c042..ade3c4dc5bf87d1495c779c47ecc84d816ac6aa7 100644
--- a/fixincludes/fixfixes.c
+++ b/fixincludes/fixfixes.c
@@ -3,7 +3,7 @@
 
    Test to see if a particular fix should be applied to a header file.
 
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
    Free Software Foundation, Inc.
 
 = = = = = = = = = = = = = = = = = = = = = = = = =
@@ -749,6 +749,8 @@ main( int argc, char** argv )
       return EXIT_FAILURE;
     }
 
+  initialize_opts ();
+
   {
     char* pz = argv[1];
     long  idx;
diff --git a/fixincludes/fixincl.c b/fixincludes/fixincl.c
index 690184b8ad7a3bc28127fc08db62c5c9067ba4d5..a153a777a54a148c2eb21f4a626b6554d9f593ce 100644
--- a/fixincludes/fixincl.c
+++ b/fixincludes/fixincl.c
@@ -2,7 +2,7 @@
    files which are fixed to work correctly with ANSI C and placed in a
    directory that GCC will search.
 
-   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -23,6 +23,8 @@ Boston, MA 02111-1307, USA.  */
 
 #include "fixlib.h"
 
+#include <sys/stat.h>
+
 #if defined( HAVE_MMAP_FILE )
 #include <sys/mman.h>
 #define  BAD_ADDR ((void*)-1)
@@ -49,12 +51,6 @@ static const char z_std_preamble[] =
     This had to be done to correct non-standard usages in the\n\
     original, manufacturer supplied header file.  */\n\n";
 
-/*  Working environment strings.  Essentially, invocation 'options'.  */
-
-#define _ENV_(v,m,n,t)   tCC* v = NULL;
-ENV_TABLE
-#undef _ENV_
-
 int find_base_len = 0;
 
 typedef enum {
@@ -214,18 +210,6 @@ do_version (void)
 void
 initialize ( int argc, char** argv )
 {
-  static const char var_not_found[] =
-#ifndef __STDC__
-    "fixincl ERROR:  %s environment variable not defined\n"
-#else
-    "fixincl ERROR:  %s environment variable not defined\n"
-    "each of these must be defined:\n"
-# define _ENV_(vv,mm,nn,tt) "\t" nn "  - " tt "\n"
-  ENV_TABLE
-# undef _ENV_
-#endif
-    ;
-
   xmalloc_set_program_name (argv[0]);
 
   switch (argc)
@@ -255,14 +239,7 @@ initialize ( int argc, char** argv )
   signal (SIGCHLD, SIG_DFL);
 #endif
 
-#define _ENV_(v,m,n,t)   { tSCC var[] = n;  \
-  v = getenv (var); if (m && (v == NULL)) { \
-  fprintf (stderr, var_not_found, var);     \
-  exit (EXIT_FAILURE); } }
-
-ENV_TABLE
-
-#undef _ENV_
+  initialize_opts ();
 
   if (ISDIGIT ( *pz_verbose ))
     verbose_level = (te_verbose)atoi( pz_verbose );
@@ -877,32 +854,41 @@ fix_with_system (tFixDesc* p_fixd,
   char*  pz_cmd;
   char*  pz_scan;
   size_t argsize;
+  int i;
+  tSCC z_applyfix_prog[2] = {
+    "/../fixincludes/applyfix" EXE_EXT,
+    "/../../fixincludes/applyfix" EXE_EXT };
 
   if (p_fixd->fd_flags & FD_SUBROUTINE)
-    {
-      tSCC z_applyfix_prog[] = "/fixinc/applyfix";
-
-      argsize = 32
-              + strlen( pz_orig_dir )
-              + sizeof( z_applyfix_prog )
-              + strlen( pz_fix_file )
-              + strlen( pz_file_source )
-              + strlen( pz_temp_file );
-
-      pz_cmd = xmalloc (argsize);
-
-      strcpy( pz_cmd, pz_orig_dir );
-      pz_scan = pz_cmd + strlen( pz_orig_dir );
-      strcpy( pz_scan, z_applyfix_prog );
-      pz_scan += sizeof( z_applyfix_prog ) - 1;
-      *(pz_scan++) = ' ';
-
-      /*
-       *  Now add the fix number and file names that may be needed
-       */
-      sprintf (pz_scan, "%ld \'%s\' \'%s\' \'%s\'", p_fixd - fixDescList,
-	       pz_fix_file, pz_file_source, pz_temp_file);
-    }
+    for (i = 0; i < 2; i++)
+      { 
+	struct stat buf;
+
+        argsize = 32
+                + strlen( pz_orig_dir )
+                + sizeof( z_applyfix_prog )
+                + strlen( pz_fix_file )
+                + strlen( pz_file_source )
+                + strlen( pz_temp_file );
+
+        pz_cmd = xmalloc (argsize);
+
+        strcpy( pz_cmd, pz_orig_dir );
+        pz_scan = pz_cmd + strlen( pz_orig_dir );
+        strcpy( pz_scan, z_applyfix_prog );
+        pz_scan += sizeof( z_applyfix_prog ) - 1;
+
+	if (stat (pz_scan, &buf) != -1)
+	  {
+            *(pz_scan++) = ' ';
+            /*
+             *  Now add the fix number and file names that may be needed
+             */
+            sprintf (pz_scan, "%ld \'%s\' \'%s\' \'%s\'", p_fixd - fixDescList,
+	             pz_fix_file, pz_file_source, pz_temp_file);
+	    break;
+	  }
+      }
   else /* NOT an "internal" fix: */
     {
       size_t parg_size;
diff --git a/fixincludes/fixlib.c b/fixincludes/fixlib.c
index e0fa94a14badec5816168abba210bbfa96a28821..e56328b162191582690a9712fee7fd5c60f49f8b 100644
--- a/fixincludes/fixlib.c
+++ b/fixincludes/fixlib.c
@@ -3,7 +3,7 @@
    files which are fixed to work correctly with ANSI C and placed in a
    directory that GCC will search.
 
-   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
diff --git a/fixincludes/fixlib.h b/fixincludes/fixlib.h
index 4993d1bd654fed73a1a799cadb6f83e14b0ac901..0ceb60b76268f97681c16b068c72912cc9c83980 100644
--- a/fixincludes/fixlib.h
+++ b/fixincludes/fixlib.h
@@ -224,4 +224,6 @@ char*  make_raw_shell_str ( char* pz_d, tCC* pz_s, size_t smax );
 #endif
 
 t_bool mn_get_regexps ( regex_t** label_re, regex_t** name_re, tCC *who );
+
+void   initialize_opts ( void );
 #endif /* ! GCC_FIXLIB_H */
diff --git a/fixincludes/fixopts.c b/fixincludes/fixopts.c
new file mode 100644
index 0000000000000000000000000000000000000000..55a85e9b6f46303c25a9df739dbbeb106e114c19
--- /dev/null
+++ b/fixincludes/fixopts.c
@@ -0,0 +1,51 @@
+/* Handle options that are passed from environment variables.
+
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "fixlib.h"
+
+#define _ENV_(v,m,n,t)   tCC* v = NULL;
+ENV_TABLE
+#undef _ENV_
+
+void
+initialize_opts ()
+{
+  static const char var_not_found[] =
+#ifndef __STDC__
+    "fixincl ERROR:  %s environment variable not defined\n"
+#else
+    "fixincl ERROR:  %s environment variable not defined\n"
+    "each of these must be defined:\n"
+# define _ENV_(vv,mm,nn,tt) "\t" nn "  - " tt "\n"
+  ENV_TABLE
+# undef _ENV_
+#endif
+    ;
+
+#define _ENV_(v,m,n,t)   { tSCC var[] = n;  \
+  v = getenv (var); if (m && (v == NULL)) { \
+  fprintf (stderr, var_not_found, var);     \
+  exit (EXIT_FAILURE); } }
+
+ENV_TABLE
+
+#undef _ENV_
+}