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: Improve native Windows support on csl-arm-branch


This patch incorporates some work done mostly by Zack on the
csl-arm-branch.  It makes GCC work much better when built as a native
Windows (rather than Cygwin) application.  This patch is being
installed only on the csl-arm-branch because DJ didn't want the last
version in libiberty in its current form, and we've not done anything
since that point that would be likely to overcome DJ's objections.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-12-23  Zack Weinberg  <zack@codesourcery.com>
	    Nathan Sidwell  <nathan@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* collect2.c (windows.h): Include.
	(dup2): Remove.
	(handler): Change prototype.
	(unhandled_filter): New funciton.
	(install_handlers): Likewise.
	(disable_break): Likewise.
	(enable_break): Likewise.
	(main): Call install_handlers rather than signal directly.
	(collect_execute): Use pexec.
	(scan_prog_file): Likewise.
	(scan_libraries): Likewise.

2003-12-23  Zack Weinberg  <zack@codesourcery.com>
	    Nathan Sidwell  <nathan@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* libiberty.h (pmkpipe): New function.
	(pexec): Likewise.
	(pexec_set_program_name): Likewise.
	(WIFSIGNALED): Define.
	(WTERMSIG): Likewise.
	(WIFEXITED): Likewise.
	(WEXITSTATUS): Likewise.
	(WSTOPSIG): Likewise.
	(WCOREDUMP): Likewise.

2003-12-23  Zack Weinberg  <zack@codesourcery.com>
	    Nathan Sidwell  <nathan@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* pex-common.c (STDERR_FILE_NO): Define.
	* pex-win32.c: Rework extensively.

Index: gcc/collect2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/collect2.c,v
retrieving revision 1.154
diff -c -5 -p -r1.154 collect2.c
*** gcc/collect2.c	17 Oct 2003 11:27:13 -0000	1.154
--- gcc/collect2.c	23 Dec 2003 17:16:29 -0000
*************** Software Foundation, 59 Temple Place - S
*** 28,54 ****
  
  #include "config.h"
  #include "system.h"
  #include "coretypes.h"
  #include "tm.h"
! #include <signal.h>
! #if ! defined( SIGCHLD ) && defined( SIGCLD )
! #  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
  
--- 28,46 ----
  
  #include "config.h"
  #include "system.h"
  #include "coretypes.h"
  #include "tm.h"
! #ifdef _WIN32
! # define WIN32_LEAN_AND_MEAN
! # include <windows.h>
  #else
! # include <signal.h>
! # if ! defined( SIGCHLD ) && defined( SIGCLD )
! #  define SIGCHLD SIGCLD
! # endif
! #endif 
  
  #ifndef LIBRARY_PATH_ENV
  #define LIBRARY_PATH_ENV "LIBRARY_PATH"
  #endif
  
*************** static struct path_prefix libpath_lib_di
*** 247,257 ****
  static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
  					  &libpath_lib_dirs, NULL};
  static const char *const libexts[3] = {"a", "so", NULL};  /* possible library extensions */
  #endif
  
! static void handler (int);
  static int is_ctor_dtor (const char *);
  static char *find_a_file (struct path_prefix *, const char *);
  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 *);
--- 239,259 ----
  static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
  					  &libpath_lib_dirs, NULL};
  static const char *const libexts[3] = {"a", "so", NULL};  /* possible library extensions */
  #endif
  
! static void clean_up_temp_files	(void);
! #ifdef _WIN32
! static BOOL WINAPI handler	(DWORD);
! static LONG unhanded_filter	(LPEXCEPTION_POINTERS);
! #else
! static void handler		(int);
! #endif
! static void install_handlers	(void);
! static void disable_break	(void);
! static void enable_break	(void);
! 
  static int is_ctor_dtor (const char *);
  static char *find_a_file (struct path_prefix *, const char *);
  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 is_in_list (const char *, str
*** 288,317 ****
  static void write_aix_file (FILE *, struct id *);
  static char *resolve_lib_name (const char *);
  #endif
  static char *extract_string (const char **);
  
- #ifndef HAVE_DUP2
- static int
- dup2 (int oldfd, int newfd)
- {
-   int fdtmp[256];
-   int fdx = 0;
-   int fd;
- 
-   if (oldfd == newfd)
-     return oldfd;
-   close (newfd);
-   while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
-     fdtmp[fdx++] = fd;
-   while (fdx > 0)
-     close (fdtmp[--fdx]);
- 
-   return fd;
- }
- #endif /* ! HAVE_DUP2 */
- 
  /* Delete tempfiles and exit function.  */
  
  void
  collect_exit (int status)
  {
--- 290,299 ----
*************** fancy_abort (void)
*** 405,415 ****
  {
    fatal ("internal error");
  }
  
  static void
! handler (int signo)
  {
    if (c_file != 0 && c_file[0])
      maybe_unlink (c_file);
  
    if (o_file != 0 && o_file[0])
--- 387,397 ----
  {
    fatal ("internal error");
  }
  
  static void
! clean_up_temp_files (void)
  {
    if (c_file != 0 && c_file[0])
      maybe_unlink (c_file);
  
    if (o_file != 0 && o_file[0])
*************** handler (int signo)
*** 420,434 ****
--- 402,522 ----
  
  #ifdef COLLECT_EXPORT_LIST
    if (export_file != 0 && export_file[0])
      maybe_unlink (export_file);
  #endif
+ }  
  
+ /* Signal handling needs to be drastically different between Windows
+    and Unix.  */
+ #ifdef _WIN32
+   
+ static BOOL WINAPI
+ handler (DWORD signo ATTRIBUTE_UNUSED)
+ {
+   clean_up_temp_files ();
+   return FALSE; /* not handled - default handler will terminate process */
+ }
+ 
+ static LONG
+ unhandled_filter (LPEXCEPTION_POINTERS pointers ATTRIBUTE_UNUSED)
+ {
+   clean_up_temp_files ();
+   return EXCEPTION_CONTINUE_SEARCH;   /* carry on and terminate process */
+ }
+ 
+ 
+ static void
+ install_handlers (void)
+ {
+   SetConsoleCtrlHandler (handler, TRUE);
+   /* This is not really the right way to do this; in fact I'm not
+      sure it will work.  But it might.  */
+   SetUnhandledExceptionFilter (unhandled_filter);
+ }
+ 
+ static void
+ disable_break (void)
+ {
+   /* This only works on Windows NT, and only disables CTRL-C;
+      CTRL-BREAK is not disabled (but does get caught by the handler).  */
+   if (!(GetVersion() & 0x80000000))
+     SetConsoleCtrlHandler (NULL, TRUE);
+ }
+ 
+ static void
+ enable_break (void)
+ {
+   if (!(GetVersion() & 0x80000000))
+     SetConsoleCtrlHandler (NULL, FALSE);
+ }
+ 
+ #else /* not _WIN32 */
+ 
+ static void
+ handler (int signo)
+ {
+   clean_up_temp_files ();
    signal (signo, SIG_DFL);
    kill (getpid (), signo);
  }
  
+ static void
+ install_handlers ()
+ {
+ #ifdef SIGQUIT
+   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
+     signal (SIGQUIT, handler);
+ #endif
+   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
+     signal (SIGINT, handler);
+ #ifdef SIGALRM
+   if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
+     signal (SIGALRM, handler);
+ #endif
+ #ifdef SIGHUP
+   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
+     signal (SIGHUP, handler);
+ #endif
+   if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
+     signal (SIGSEGV, handler);
+ #ifdef SIGBUS
+   if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
+     signal (SIGBUS, handler);
+ #endif
+ #ifdef SIGCHLD
+   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+      receive the signal.  A different setting is inheritable */
+   signal (SIGCHLD, SIG_DFL);
+ #endif
+ }
+ 
+ static void (*int_handler) PARAMS ((int));
+ #ifdef SIGQUIT
+ static void (*quit_handler) PARAMS ((int));
+ #endif
+ 
+ static void
+ disable_break ()
+ {
+   int_handler  = (void (*) PARAMS ((int))) signal (SIGINT,  SIG_IGN);
+ #ifdef SIGQUIT
+   quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
+ #endif
+ }
+ 
+ static void
+ enable_break ()
+ {
+   signal (SIGINT,  int_handler);
+ #ifdef SIGQUIT
+   signal (SIGQUIT, quit_handler);
+ #endif
+ }
+ 
+ #endif /* not _WIN32 */
+ 
  
  int
  file_exists (const char *name)
  {
    return access (name, R_OK) == 0;
*************** main (int argc, char **argv)
*** 819,844 ****
    char **object_lst;
    const char **object;
    int first_file;
    int num_c_args	= argc+9;
  
    no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
  
    /* Suppress demangling by the real linker, which may be broken.  */
    putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
  
  #if defined (COLLECT2_HOST_INITIALIZATION)
    /* Perform system dependent initialization, if necessary.  */
    COLLECT2_HOST_INITIALIZATION;
  #endif
  
- #ifdef SIGCHLD
-   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
-      receive the signal.  A different setting is inheritable */
-   signal (SIGCHLD, SIG_DFL);
- #endif
- 
    gcc_init_libintl ();
  
    /* Do not invoke xcalloc before this point, since locale needs to be
       set first, in case a diagnostic is issued.  */
  
--- 907,928 ----
    char **object_lst;
    const char **object;
    int first_file;
    int num_c_args	= argc+9;
  
+   pexec_set_program_name (argv[0]);
+ 
    no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
  
    /* Suppress demangling by the real linker, which may be broken.  */
    putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
  
  #if defined (COLLECT2_HOST_INITIALIZATION)
    /* Perform system dependent initialization, if necessary.  */
    COLLECT2_HOST_INITIALIZATION;
  #endif
  
    gcc_init_libintl ();
  
    /* Do not invoke xcalloc before this point, since locale needs to be
       set first, in case a diagnostic is issued.  */
  
*************** main (int argc, char **argv)
*** 890,919 ****
    c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
  
    if (argc < 2)
      fatal ("no arguments");
  
! #ifdef SIGQUIT
!   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
!     signal (SIGQUIT, handler);
! #endif
!   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
!     signal (SIGINT, handler);
! #ifdef SIGALRM
!   if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
!     signal (SIGALRM, handler);
! #endif
! #ifdef SIGHUP
!   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
!     signal (SIGHUP, handler);
! #endif
!   if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
!     signal (SIGSEGV, handler);
! #ifdef SIGBUS
!   if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
!     signal (SIGBUS, handler);
! #endif
  
    /* Extract COMPILER_PATH and PATH into our prefix list.  */
    prefix_from_env ("COMPILER_PATH", &cpath);
    prefix_from_env ("PATH", &path);
  
--- 974,984 ----
    c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
  
    if (argc < 2)
      fatal ("no arguments");
  
!   install_handlers ();
  
    /* Extract COMPILER_PATH and PATH into our prefix list.  */
    prefix_from_env ("COMPILER_PATH", &cpath);
    prefix_from_env ("PATH", &path);
  
*************** do_wait (const char *prog)
*** 1490,1504 ****
  /* Execute a program, and wait for the reply.  */
  
  void
  collect_execute (const char *prog, char **argv, const char *redir)
  {
-   char *errmsg_fmt;
-   char *errmsg_arg;
    int redir_handle = -1;
-   int stdout_save = -1;
-   int stderr_save = -1;
  
    if (vflag || debug)
      {
        char **p_argv;
        const char *str;
--- 1555,1565 ----
*************** collect_execute (const char *prog, char 
*** 1512,1564 ****
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
-   fflush (stdout);
-   fflush (stderr);
- 
    /* If we cannot find a program we need, complain error.  Do this here
       since we might not end up needing something that we could not find.  */
  
    if (argv[0] == 0)
      fatal ("cannot find `%s'", prog);
  
    if (redir)
!     {
!       /* Open response file.  */
!       redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
! 
!       /* Duplicate the stdout and stderr file handles
! 	 so they can be restored later.  */
!       stdout_save = dup (STDOUT_FILENO);
!       if (stdout_save == -1)
! 	fatal_perror ("redirecting stdout: %s", redir);
!       stderr_save = dup (STDERR_FILENO);
!       if (stderr_save == -1)
! 	fatal_perror ("redirecting stdout: %s", redir);
! 
!       /* Redirect stdout & stderr to our response file.  */
!       dup2 (redir_handle, STDOUT_FILENO);
!       dup2 (redir_handle, STDERR_FILENO);
!     }
! 
!   pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
! 		  (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
! 
!   if (redir)
!     {
!       /* Restore stdout and stderr to their previous settings.  */
!       dup2 (stdout_save, STDOUT_FILENO);
!       dup2 (stderr_save, STDERR_FILENO);
  
!       /* Close response file.  */
!       close (redir_handle);
!     }
  
!  if (pid == -1)
!    fatal_perror (errmsg_fmt, errmsg_arg);
  }
  
  static void
  fork_execute (const char *prog, char **argv)
  {
--- 1573,1595 ----
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
    /* If we cannot find a program we need, complain error.  Do this here
       since we might not end up needing something that we could not find.  */
  
    if (argv[0] == 0)
      fatal ("cannot find `%s'", prog);
  
    if (redir)
!     redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
  
!   pid = pexec (argv[0], argv, 1, -1, redir_handle, -1);
  
!   if (pid == -1)
!    fatal_perror ("pexec");
  }
  
  static void
  fork_execute (const char *prog, char **argv)
  {
*************** write_aix_file (FILE *stream, struct id 
*** 1982,1993 ****
     destructor table has the same format, and begins at __DTOR_LIST__.  */
  
  static void
  scan_prog_file (const char *prog_name, enum pass which_pass)
  {
-   void (*int_handler) (int);
-   void (*quit_handler) (int);
    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];
--- 2013,2022 ----
*************** scan_prog_file (const char *prog_name, e
*** 2005,2015 ****
      nm_argv[argc++] = NM_FLAGS;
  
    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");
--- 2034,2044 ----
      nm_argv[argc++] = NM_FLAGS;
  
    nm_argv[argc++] = prog_name;
    nm_argv[argc++] = (char *) 0;
  
!   if (pmkpipe (pipe_fd) < 0)
      fatal_perror ("pipe");
  
    inf = fdopen (pipe_fd[0], "r");
    if (inf == (FILE *) 0)
      fatal_perror ("fdopen");
*************** scan_prog_file (const char *prog_name, e
*** 2024,2065 ****
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
-   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);
!     }
! 
    /* 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");
  
    /* Read each line of nm output.  */
--- 2053,2070 ----
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
    /* Spawn child nm on pipe.  */
!   pid = pexec (nm_file_name, real_nm_argv, 0, -1, pipe_fd[1], -1);
!   
    if (pid == -1)
!     fatal_perror ("pexec");
!   
    /* Parent context from here on.  */
!   disable_break ();
  
    if (debug)
      fprintf (stderr, "\nnm output with constructors/destructors.\n");
  
    /* Read each line of nm output.  */
*************** scan_prog_file (const char *prog_name, e
*** 2134,2147 ****
    if (fclose (inf) != 0)
      fatal_perror ("fclose");
  
    do_wait (nm_file_name);
  
!   signal (SIGINT,  int_handler);
! #ifdef SIGQUIT
!   signal (SIGQUIT, quit_handler);
! #endif
  }
  
  #if SUNOS4_SHARED_LIBRARIES
  
  /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
--- 2139,2149 ----
    if (fclose (inf) != 0)
      fatal_perror ("fclose");
  
    do_wait (nm_file_name);
  
!   enable_break ();
  }
  
  #if SUNOS4_SHARED_LIBRARIES
  
  /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
*************** scan_libraries (const char *prog_name)
*** 2414,2425 ****
  static void
  scan_libraries (const char *prog_name)
  {
    static struct head libraries;		/* list of shared libraries found */
    struct id *list;
-   void (*int_handler) (int);
-   void (*quit_handler) (int);
    char *real_ldd_argv[4];
    const char **ldd_argv = (const char **) real_ldd_argv;
    int argc = 0;
    int pipe_fd[2];
    char buf[1024];
--- 2416,2425 ----
*************** scan_libraries (const char *prog_name)
*** 2434,2444 ****
  
    ldd_argv[argc++] = ldd_file_name;
    ldd_argv[argc++] = prog_name;
    ldd_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");
--- 2434,2444 ----
  
    ldd_argv[argc++] = ldd_file_name;
    ldd_argv[argc++] = prog_name;
    ldd_argv[argc++] = (char *) 0;
  
!   if (pmkpipe (pipe_fd) < 0)
      fatal_perror ("pipe");
  
    inf = fdopen (pipe_fd[0], "r");
    if (inf == (FILE *) 0)
      fatal_perror ("fdopen");
*************** scan_libraries (const char *prog_name)
*** 2453,2494 ****
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
-   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);
!     }
  
    /* 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)
      notice ("\nldd output with constructors/destructors.\n");
  
    /* Read each line of ldd output.  */
--- 2453,2470 ----
  	fprintf (stderr, " %s", str);
  
        fprintf (stderr, "\n");
      }
  
    /* Spawn child ldd on pipe.  */
!   pexecute_pid = pexec (ldd_file_name, real_ldd_argv, 0, -1, infpipe[1], -1);
!   
!   if (pexecute_pid == -1)
!     fatal_perror ("pexec");
  
    /* Parent context from here on.  */
!   disable_break ();
  
    if (debug)
      notice ("\nldd output with constructors/destructors.\n");
  
    /* Read each line of ldd output.  */
*************** scan_libraries (const char *prog_name)
*** 2527,2541 ****
    if (fclose (inf) != 0)
      fatal_perror ("fclose");
  
    do_wait (ldd_file_name);
  
!   signal (SIGINT,  int_handler);
! #ifdef SIGQUIT
!   signal (SIGQUIT, quit_handler);
! #endif
! 
    /* now iterate through the library list adding their symbols to
       the list.  */
    for (list = libraries.first; list; list = list->next)
      scan_prog_file (list->name, PASS_LIB);
  }
--- 2503,2513 ----
    if (fclose (inf) != 0)
      fatal_perror ("fclose");
  
    do_wait (ldd_file_name);
  
!   enable_break ();
    /* now iterate through the library list adding their symbols to
       the list.  */
    for (list = libraries.first; list; list = list->next)
      scan_prog_file (list->name, PASS_LIB);
  }
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.35
diff -c -5 -p -r1.35 libiberty.h
*** include/libiberty.h	15 May 2003 19:02:12 -0000	1.35
--- include/libiberty.h	23 Dec 2003 17:16:30 -0000
*************** extern char **dupargv PARAMS ((char **))
*** 72,82 ****
     undefined, we haven't run the autoconf check so provide the
     declaration without arguments.  If it is 0, we checked and failed
     to find the declaration so provide a fully prototyped one.  If it
     is 1, we found it so don't provide any declaration at all.  */
  #if !HAVE_DECL_BASENAME
! #if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (HAVE_DECL_BASENAME)
  extern char *basename PARAMS ((const char *));
  #else
  extern char *basename ();
  #endif
  #endif
--- 72,82 ----
     undefined, we haven't run the autoconf check so provide the
     declaration without arguments.  If it is 0, we checked and failed
     to find the declaration so provide a fully prototyped one.  If it
     is 1, we found it so don't provide any declaration at all.  */
  #if !HAVE_DECL_BASENAME
! #if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__sun__) || defined (HAVE_DECL_BASENAME)
  extern char *basename PARAMS ((const char *));
  #else
  extern char *basename ();
  #endif
  #endif
*************** extern void hex_init PARAMS ((void));
*** 272,284 ****
  /* 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.  */
  
--- 272,339 ----
  /* Execute a program.  */
  
  extern int pexecute PARAMS ((const char *, char * const *, const char *,
  			    const char *, char **, char **, int));
  
! /* Slightly lower level routines which are more flexible than pexecute:  */
! extern int pmkpipe PARAMS ((int[2]));
! 
! extern int pexec PARAMS ((const char *, char * const *, int, int, int, int));
! 
! /* Wait for a process created by pexecute or pexec to finish.  */
  
  extern int pwait PARAMS ((int, int *, int));
+ 
+ /* Set the program name used for error messages by pexec.  */
+ extern void pexec_set_program_name PARAMS ((const char *));
+ 
+ #if !defined(_WIN32) || defined(__CYGWIN__)
+ 
+ #ifndef WIFSIGNALED
+ #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
+ #endif
+ #ifndef WTERMSIG
+ #define WTERMSIG(S) ((S) & 0x7f)
+ #endif
+ #ifndef WIFEXITED
+ #define WIFEXITED(S) (((S) & 0xff) == 0)
+ #endif
+ #ifndef WEXITSTATUS
+ #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+ #endif
+ #ifndef WSTOPSIG
+ #define WSTOPSIG WEXITSTATUS
+ #endif
+ #ifndef WCOREDUMP
+ #define WCOREDUMP(S) ((S) & WCOREFLG)
+ #endif
+ #ifndef WCOREFLG
+ #define WCOREFLG 0200
+ #endif
+ 
+ #else /* defined(_WIN32) && ! defined(__CYGWIN__) */
+ 
+ #ifndef WIFSIGNALED
+ #define WIFSIGNALED(S)  ((void)(S), 0)
+ #endif
+ #ifndef WTERMSIG
+ #define WTERMSIG(S) ((void)(S), 0)
+ #endif
+ #ifndef WIFEXITED
+ #define WIFEXITED(S) ((void)(S), 1)
+ #endif
+ #ifndef WEXITSTATUS
+ #define WEXITSTATUS(S) (S)
+ #endif
+ #ifndef WSTOPSIG
+ #define WSTOPSIG WEXITSTATUS
+ #endif
+ #ifndef WCOREDUMP
+ #define WCOREDUMP(S) ((void)(S), 0)
+ #endif
+ 
+ #endif
  
  #if !HAVE_DECL_ASPRINTF
  /* Like sprintf but provides a pointer to malloc'd storage, which must
     be freed by the caller.  */
  
Index: libiberty/pex-common.h
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pex-common.h,v
retrieving revision 1.1
diff -c -5 -p -r1.1 pex-common.h
*** libiberty/pex-common.h	24 Jan 2003 20:02:11 -0000	1.1
--- libiberty/pex-common.h	23 Dec 2003 17:16:30 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 31,40 ****
--- 31,43 ----
  #define STDIN_FILE_NO 0
  
  /* stdout file number.  */
  #define STDOUT_FILE_NO 1
  
+ /* stderr file number.  */
+ #define STDERR_FILE_NO 2
+ 
  /* value of `pipe': port index for reading.  */
  #define READ_PORT 0
  
  /* value of `pipe': port index for writing.  */
  #define WRITE_PORT 1
Index: libiberty/pex-win32.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/pex-win32.c,v
retrieving revision 1.3
diff -c -5 -p -r1.3 pex-win32.c
*** libiberty/pex-win32.c	5 Jul 2003 00:52:07 -0000	1.3
--- libiberty/pex-win32.c	23 Dec 2003 17:16:30 -0000
*************** License along with libiberty; see the fi
*** 19,250 ****
  write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
  #include "pex-common.h"
  
! #ifdef HAVE_STRING_H
! #include <string.h>
! #endif
! #ifdef HAVE_UNISTD_H
! #include <unistd.h>
! #endif
! #ifdef HAVE_SYS_WAIT_H
! #include <sys/wait.h>
! #endif
! 
! #include <process.h>
  #include <io.h>
  #include <fcntl.h>
! #include <signal.h>
  
! /* mingw32 headers may not define the following.  */
  
! #ifndef _P_WAIT
! #  define _P_WAIT	0
! #  define _P_NOWAIT	1
! #  define _P_OVERLAY	2
! #  define _P_NOWAITO	3
! #  define _P_DETACH	4
! 
! #  define WAIT_CHILD		0
! #  define WAIT_GRANDCHILD	1
! #endif
! 
! /* This is a kludge to get around the Microsoft C spawn functions' propensity
!    to remove the outermost set of double quotes from all arguments.  */
! 
! static const char * const *
! fix_argv (argvec)
!      char **argvec;
! {
!   int i;
!   char * command0 = argvec[0];
! 
!   /* Ensure that the executable pathname uses Win32 backslashes.  */
!   for (; *command0 != '\0'; command0++)
!     if (*command0 == '/')
!       *command0 = '\\';
!  
!   for (i = 1; argvec[i] != 0; i++)
      {
!       int len, j;
!       char *temp, *newtemp;
  
!       temp = argvec[i];
!       len = strlen (temp);
!       for (j = 0; j < len; j++)
!         {
!           if (temp[j] == '"')
!             {
!               newtemp = xmalloc (len + 2);
!               strncpy (newtemp, temp, j);
!               newtemp [j] = '\\';
!               strncpy (&newtemp [j+1], &temp [j], len-j);
!               newtemp [len+1] = 0;
!               temp = newtemp;
!               len++;
!               j++;
!             }
!         }
! 
!         argvec[i] = temp;
!       }
! 
!   for (i = 0; argvec[i] != 0; i++)
!     {
!       if (strpbrk (argvec[i], " \t"))
!         {
! 	  int len, trailing_backslash;
! 	  char *temp;
! 
! 	  len = strlen (argvec[i]);
! 	  trailing_backslash = 0;
! 
! 	  /* There is an added complication when an arg with embedded white
! 	     space ends in a backslash (such as in the case of -iprefix arg
! 	     passed to cpp). The resulting quoted strings gets misinterpreted
! 	     by the command interpreter -- it thinks that the ending quote
! 	     is escaped by the trailing backslash and things get confused. 
! 	     We handle this case by escaping the trailing backslash, provided
! 	     it was not escaped in the first place.  */
! 	  if (len > 1 
! 	      && argvec[i][len-1] == '\\' 
! 	      && argvec[i][len-2] != '\\')
! 	    {
! 	      trailing_backslash = 1;
! 	      ++len;			/* to escape the final backslash. */
! 	    }
! 
! 	  len += 2;			/* and for the enclosing quotes. */
! 
! 	  temp = xmalloc (len + 1);
! 	  temp[0] = '"';
! 	  strcpy (temp + 1, argvec[i]);
! 	  if (trailing_backslash)
! 	    temp[len-2] = '\\';
! 	  temp[len-1] = '"';
! 	  temp[len] = '\0';
  
! 	  argvec[i] = temp;
  	}
      }
  
!   return (const char * const *) argvec;
  }
  
- /* Win32 supports pipes */
  int
  pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
       const char *program;
       char * const *argv;
       const char *this_pname ATTRIBUTE_UNUSED;
       const char *temp_base ATTRIBUTE_UNUSED;
       char **errmsg_fmt, **errmsg_arg;
       int flags;
  {
    int pid;
!   int pdes[2];
!   int org_stdin = -1;
!   int org_stdout = -1;
!   int input_desc, output_desc;
! 
!   /* Pipe waiting from last process, to be used as input for the next one.
!      Value is STDIN_FILE_NO if no pipe is waiting
!      (i.e. the next command is the first of a group).  */
!   static int last_pipe_input;
  
!   /* If this is the first process, initialize.  */
    if (flags & PEXECUTE_FIRST)
!     last_pipe_input = STDIN_FILE_NO;
  
!   input_desc = last_pipe_input;
  
!   /* If this isn't the last process, make a pipe for its output,
!      and record it as waiting to be the input to the next process.  */
!   if (! (flags & PEXECUTE_LAST))
      {
!       if (_pipe (pdes, 256, O_BINARY) < 0)
  	{
  	  *errmsg_fmt = "pipe";
  	  *errmsg_arg = NULL;
  	  return -1;
  	}
!       output_desc = pdes[WRITE_PORT];
!       last_pipe_input = pdes[READ_PORT];
!     }
!   else
!     {
!       /* Last process.  */
!       output_desc = STDOUT_FILE_NO;
!       last_pipe_input = STDIN_FILE_NO;
!     }
! 
!   if (input_desc != STDIN_FILE_NO)
!     {
!       org_stdin = dup (STDIN_FILE_NO);
!       dup2 (input_desc, STDIN_FILE_NO);
!       close (input_desc); 
      }
  
!   if (output_desc != STDOUT_FILE_NO)
!     {
!       org_stdout = dup (STDOUT_FILE_NO);
!       dup2 (output_desc, STDOUT_FILE_NO);
!       close (output_desc);
!     }
  
!   pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
!     (_P_NOWAIT, program, fix_argv(argv));
  
!   if (input_desc != STDIN_FILE_NO)
!     {
!       dup2 (org_stdin, STDIN_FILE_NO);
!       close (org_stdin);
!     }
  
!   if (output_desc != STDOUT_FILE_NO)
!     {
!       dup2 (org_stdout, STDOUT_FILE_NO);
!       close (org_stdout);
!     }
  
    if (pid == -1)
      {
!       *errmsg_fmt = install_error_msg;
!       *errmsg_arg = (char*) program;
!       return -1;
      }
  
    return pid;
  }
  
- /* MS CRTDLL doesn't return enough information in status to decide if the
-    child exited due to a signal or not, rather it simply returns an
-    integer with the exit code of the child; eg., if the child exited with 
-    an abort() call and didn't have a handler for SIGABRT, it simply returns
-    with status = 3. We fix the status code to conform to the usual WIF*
-    macros. Note that WIFSIGNALED will never be true under CRTDLL. */
- 
  int
  pwait (pid, status, flags)
       int pid;
       int *status;
       int flags ATTRIBUTE_UNUSED;
  {
!   int termstat;
! 
!   pid = _cwait (&termstat, pid, WAIT_CHILD);
! 
!   /* ??? Here's an opportunity to canonicalize the values in STATUS.
!      Needed?  */
! 
!   /* cwait returns the child process exit code in termstat.
!      A value of 3 indicates that the child caught a signal, but not
!      which one.  Since only SIGABRT, SIGFPE and SIGINT do anything, we
!      report SIGABRT.  */
!   if (termstat == 3)
!     *status = SIGABRT;
!   else
!     *status = (((termstat) & 0xff) << 8);
  
    return pid;
  }
--- 19,413 ----
  write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
  #include "pex-common.h"
  
! #define WIN32_LEAN_AND_MEAN
! #include <windows.h>
  #include <io.h>
  #include <fcntl.h>
! #include <string.h>
! #include <stdlib.h>
  
! static const char *this_program;
  
! #define xclose(fd) do {					\
!   if (fd != -1)						\
!     {							\
!       _close (fd);					\
!       fd = -1;						\
!     }							\
! } while (0)
! 
! /* Returns a string containing a text error message, after a Windows
!    "system call" failed.  Caller is responsible for deallocating it
!    (with LocalFree()).  */
! static char *
! get_last_error_as_text ()
! {
!   DWORD last_error = GetLastError();
!   LPSTR result;
! 
!   /* We assume the error message belongs to 'the system' as opposed
!      to some module (which we would have to load, and we don't know
!      which one it is).  */
!   DWORD flags = (FORMAT_MESSAGE_ALLOCATE_BUFFER
! 		 | FORMAT_MESSAGE_IGNORE_INSERTS
! 		 | FORMAT_MESSAGE_FROM_SYSTEM);
! 
!   /* Default language.  */
!   DWORD langid = MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT);
! 
!   /* Yes, you are supposed to cast LPSTR* to LPSTR in the fifth
!      argument.  This interface is intrinsically type-unsafe.  */
!   FormatMessageA(flags, 0, last_error, langid, (LPSTR) &result, 0, 0);
! 
!   return result;
! }
!   
! static char *
! argv_to_cmdline(argv)
!      char *const *argv;
! {
!   char *cmdline;
!   char *p;
!   size_t cmdline_len;
!   int i, j;
! 
!   cmdline_len = 0;
!   for (i = 0; argv[i]; i++)
!     {
!       /* We quote every last argument.  This simplifies the problem;
! 	 we need only escape embedded double-quote and backslash
! 	 characters.  */
!       for (j = 0; argv[i][j]; j++)
! 	if (argv[i][j] == '\\' || argv[i][j] == '"')
! 	  cmdline_len++;
!       cmdline_len += j;
!       cmdline_len += 3;  /* for leading and trailing quotes and space */
!     }
! 
!   cmdline = xmalloc (cmdline_len);
!   p = cmdline;
!   for (i = 0; argv[i]; i++)
      {
!       *p++ = '"';
!       for (j = 0; argv[i][j]; j++)
! 	{
! 	  if (argv[i][j] == '\\' || argv[i][j] == '"')
! 	    *p++ = '\\';
! 	  *p++ = argv[i][j];
! 	}
!       *p++ = '"';
!       *p++ = ' ';
!     }
!   p[-1] = '\0';
!   return cmdline;
! }
  
! static const char *const
! std_suffixes[] = {
!   ".com",
!   ".exe",
!   ".bat",
!   ".cmd",
!   0
! };
! static const char *const
! no_suffixes[] = {
!   "",
!   0
! };
  
! static char *
! find_executable (program, search)
!      const char *program;
!      int search;
! {
!   char *full_executable;
!   char *e;
!   size_t fe_len;
!   const char *path = 0;
!   const char *const *ext;
!   const char *p, *q;
!   size_t proglen = strlen (program);
!   int has_extension = !!strchr (program, '.');
!   int has_slash = (strchr (program, '/') || strchr (program, '\\'));
!   HANDLE h;
! 
!   if (has_slash)
!     search = 0;
! 
!   if (search)
!     path = getenv ("PATH");
!   if (!path)
!     path = "";
! 
!   fe_len = 0;
!   for (p = path; *p; p = q)
!     {
!       q = p;
!       while (*q != ';' && *q != '\0')
! 	q++;
!       if ((size_t)(q - p) > fe_len)
! 	fe_len = q - p;
!       if (*q == ';')
! 	q++;
!     }
!   fe_len = fe_len + 1 + proglen + (has_extension ? 1 : 5);
!   full_executable = xmalloc (fe_len);
! 
!   p = path;
!   do
!     {
!       q = p;
!       while (*q != ';' && *q != '\0')
! 	q++;
! 
!       e = full_executable;
!       memcpy (e, p, q - p);
!       e += (q - p);
!       if (q - p)
! 	*e++ = '\\';
!       strcpy (e, program);
! 
!       if (*q == ';')
! 	q++;
! 
!       for (e = full_executable; *e; e++)
! 	if (*e == '/')
! 	  *e = '\\';
! 
!       /* At this point, e points to the terminating NUL character for
!          full_executable.  */
!       for (ext = has_extension ? no_suffixes : std_suffixes; *ext; ext++)
! 	{
! 	  /* Remove any current extension.  */
! 	  *e = '\0';
! 	  /* Add the new one.  */
! 	  strcat (full_executable, *ext);
! 
! 	  /* Attempt to open this file.  */
! 	  h = CreateFile (full_executable, GENERIC_READ,
! 			  FILE_SHARE_READ | FILE_SHARE_WRITE,
! 			  0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
! 	  if (h != INVALID_HANDLE_VALUE)
! 	    goto found;
  	}
+       p = q;
      }
+   while (*p);
+   free (full_executable);
+   return 0;
+ 
+  found:
+   CloseHandle (h);
+   return full_executable;
+ }
  
! int
! pexec (program, argv, search, stdin_fd, stdout_fd, stderr_fd)
!      const char *program;
!      char *const *argv;
!      int search;
!      int stdin_fd;
!      int stdout_fd;
!      int stderr_fd;
! {
!   char *cmdline = argv_to_cmdline (argv);
!   char *executable = find_executable (program, search);
!   STARTUPINFO si;
!   PROCESS_INFORMATION pinf;
!   HANDLE me;
! 
!   /* Canonicalize file descriptor arguments.  */
!   stdin_fd  = (stdin_fd == STDIN_FILE_NO)   ? -1 : stdin_fd;
!   stdout_fd = (stdout_fd == STDOUT_FILE_NO) ? -1 : stdout_fd;
!   stderr_fd = (stderr_fd == STDERR_FILE_NO) ? -1 : stderr_fd;
! 
!   memset (&si, 0, sizeof si);
!   si.cb = sizeof si;
!   si.dwFlags = STARTF_USESTDHANDLES;
! 
!   me = GetCurrentProcess();
! 
!   if (!DuplicateHandle (me,
! 		        (stdin_fd == -1)
! 			? GetStdHandle (STD_INPUT_HANDLE)
! 			: (HANDLE)_get_osfhandle (stdin_fd),
! 			me, &si.hStdInput,
! 			0, TRUE, DUPLICATE_SAME_ACCESS))
!     goto cleanup;
!   if (!DuplicateHandle (me,
! 			(stdout_fd == -1)
! 			? GetStdHandle (STD_OUTPUT_HANDLE)
! 			: (HANDLE)_get_osfhandle (stdout_fd),
! 			me, &si.hStdOutput,
! 			0, TRUE, DUPLICATE_SAME_ACCESS))
!     goto cleanup;
!   if (!DuplicateHandle (me,
! 			(stderr_fd == -1)
! 			? GetStdHandle (STD_ERROR_HANDLE)
! 			: (HANDLE)_get_osfhandle (stderr_fd),
! 			me, &si.hStdError,
! 			0, TRUE, DUPLICATE_SAME_ACCESS))
!     goto cleanup;
! 
!  
!   if (!CreateProcess (executable, cmdline,
! 		     0, 0, TRUE, 0, 0, 0,
! 		     &si, &pinf))
!     goto cleanup;
! 
!   CloseHandle (pinf.hProcess);
!   CloseHandle (pinf.hThread);
!   
!  done:
!   /* Close file descriptors passed to the child (whether or not we
!      managed to create a child).  */
!   xclose (stdin_fd);
!   xclose (stdout_fd);
!   xclose (stderr_fd);
! 
!   free (executable);
!   free (cmdline);
! 
!   return pinf.dwProcessId;
! 
!  cleanup:
!   {
!     /* Error strings on win32 include newlines.  */
!     char *errstr = get_last_error_as_text ();
!     fprintf (stderr, "%s tried to spawn %s but failed: %s",
! 	     this_program, program, errstr);
!     LocalFree (errstr);
!   }
!   CloseHandle (si.hStdInput);
!   CloseHandle (si.hStdOutput);
!   CloseHandle (si.hStdError);
!   pinf.dwProcessId = -1;
!   goto done;
! }
! 
! /* MSVCRT's _pipe() creates pipes that can be inherited, which is not
!    what we want, so we go directly to CreatePipe().  */
! int
! pmkpipe (thepipe)
!      int thepipe[2];
! {
!   HANDLE read_port;
!   HANDLE write_port;
! 
!   if (!CreatePipe (&read_port, &write_port, 0, 0))
!     return -1;
! 
!   thepipe[0] = _open_osfhandle ((long)read_port, _O_RDONLY);
!   thepipe[1] = _open_osfhandle ((long)write_port, _O_WRONLY);
!   if (thepipe[0] == -1 || thepipe[1] == -1)
!     {
!       if (thepipe[0] == -1)
! 	CloseHandle (read_port);
!       else
! 	_close (thepipe[0]);
!       if (thepipe[1] == -1)
! 	CloseHandle (write_port);
!       else
! 	_close (thepipe[1]);
!       return -1;
!     }
!   return 0;
  }
  
  int
  pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
       const char *program;
       char * const *argv;
       const char *this_pname ATTRIBUTE_UNUSED;
       const char *temp_base ATTRIBUTE_UNUSED;
       char **errmsg_fmt, **errmsg_arg;
       int flags;
  {
+   /* Pipe waiting from last process, to be used as input for the next
+      one.  Value is -1 if no pipe is waiting (i.e. the next command is
+      the first of a group).  */
+   static int last_pipe_input = -1;
+ 
    int pid;
!   int pdesc[2];
!   int serrno;
!   int child_stdin = -2, child_stdout = -2;
  
!   /* If this is the first process, last_pipe_input ought to be -1.  */
    if (flags & PEXECUTE_FIRST)
!     if (last_pipe_input != -1)
!       abort ();
  
!   child_stdin = last_pipe_input;
  
!   /* If this is the last process, don't do anything with its output
!      pipe.  */
!   if (flags & PEXECUTE_LAST)
!     child_stdout = -1;
!   else
      {
!       /* Create a pipe to go between this process and the next one in
! 	 the pipeline.  */
!       if (pmkpipe (pdesc))
  	{
  	  *errmsg_fmt = "pipe";
  	  *errmsg_arg = NULL;
  	  return -1;
  	}
!       last_pipe_input = pdesc[READ_PORT];
!       child_stdout = pdesc[WRITE_PORT];
      }
  
!   pid = pexec (program, argv, (flags & PEXECUTE_SEARCH),
! 	       child_stdin, child_stdout, -1);
  
!   serrno = errno;
!   xclose (child_stdin);
!   xclose (child_stdout);
  
!   /* To prevent a file descriptor leak, close last_pipe_input if pexec
!      failed.  */
!   if (pid == -1)
!     xclose (last_pipe_input);
  
!   errno = serrno;
  
    if (pid == -1)
      {
!       *errmsg_fmt = "spawn";
!       *errmsg_arg = NULL;
      }
  
    return pid;
  }
  
  int
  pwait (pid, status, flags)
       int pid;
       int *status;
       int flags ATTRIBUTE_UNUSED;
  {
!   HANDLE proch = OpenProcess (SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
! 			      FALSE, pid);
!   if (proch == 0)
!     return -1;
!   if (WaitForSingleObject (proch, INFINITE) != WAIT_OBJECT_0)
!     {
!       CloseHandle (proch);
!       return -1;
!     }
  
+   GetExitCodeProcess (proch, (DWORD *)status);
+   CloseHandle (proch);
    return pid;
+ }
+ 
+ void
+ pexec_set_program_name (name)
+      const char *name;
+ {
+   this_program = name;
  }


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