- Fixed a bug reported by Michael Matz regarding handling of parallel
authorPaul Smith <psmith@gnu.org>
Mon, 8 Aug 2005 05:08:00 +0000 (05:08 +0000)
committerPaul Smith <psmith@gnu.org>
Mon, 8 Aug 2005 05:08:00 +0000 (05:08 +0000)
  jobs after a failed job.
- Enhancements to WINDOWS32 code from Eli Zaretskii.
- Add Microsoft Project files from J. Grant.

19 files changed:
ChangeLog
Makefile.am
README.W32.template
build_w32.bat
commands.c
doc/make.texi
function.c
job.c
main.c
make_msvc_net2003.sln [new file with mode: 0644]
make_msvc_net2003.vcproj [new file with mode: 0644]
prepare_w32.bat
read.c
signame.c
tests/ChangeLog
tests/scripts/features/parallelism
w32/pathstuff.c
w32/subproc/build.bat
w32/subproc/sub_proc.c

index 2a22cbb185a9e07ae8992678f8fdc5c2c043b1fd..4d2c55be880f144c141f8b40fc87e4582ad4ba7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,78 @@
+2005-08-07  Paul D. Smith  <psmith@gnu.org>
+
+       * w32/pathstuff.c (getcwd_fs): Fix warning about assignment in a
+       conditional (slightly different version of a fix from Eli).
+
+       Fix a bug reported by Michael Matz <matz@suse.de>: patch included.
+       If make is running in parallel without -k and two jobs die in a
+       row, but not too close to each other, then make will quit without
+       waiting for the rest of the jobs to die.
+
+       * main.c (die): Don't reset err before calling reap_children() the
+       second time: we still want it to be in the error condition.
+       * job.c (reap_children): Use a static variable, rather than err,
+       to control whether or not the error message should be printed.
+
+2005-08-06  Eli Zaretskii  <eliz@gnu.org>
+
+       * w32/subproc/sub_proc.c: Include signal.h.
+       (process_pipe_io, process_file_io): Pass a pointer to a local
+       DWORD variable to GetExitCodeProcess.  If the exit code is
+       CONTROL_C_EXIT, put SIGINT into pproc->signal.
+
+       * job.c [WINDOWS32]: Include windows.h.
+       (main_thread) [WINDOWS32]: New global variable.
+       (reap_children) [WINDOWS32]: Get the handle for the main thread
+       and store it in main_thread.
+
+       * commands.c [WINDOWS32]: Include windows.h and w32err.h.
+       (fatal_error_signal) [WINDOWS32]: Suspend the main thread before
+       doing anything else.  When we are done, close the main thread
+       handle and exit with status 130.
+
+2005-07-30  Eli Zaretskii  <eliz@gnu.org>
+
+       * w32/subproc/sub_proc.c (process_begin): Don't pass a NULL
+       pointer to fprintf.
+
+       * main.c (find_and_set_default_shell): If found a DOSish shell,
+       set sh_found and the value of default_shell, and report the
+       findings in debug mode.
+
+       * job.c (construct_command_argv_internal): Check unixy_shell, not
+       no_default_sh_exe, to decide whether to use Unixy or DOSish
+       builtin commands.
+
+       * README.W32: Update with info about the MinGW build.
+
+       * build_w32.bat: Support MinGW.
+
+       * w32/subproc/build.bat: Likewise.
+
+       * w32/subproc/sub_proc.c (process_easy): Fix format strings for
+       printing DWORD args.
+
+       * function.c (windows32_openpipe): Fix format strings for printing
+       DWORD args.
+
+       * job.c (reap_children) [WINDOWS32]: Don't declare 'status' and
+       'reap_mode'.
+       (start_job_command): Fix format string for printing the result of
+       process_easy.
+       (start_job_command) [WINDOWS32]: Do not define.
+       (exec_command): Fix format string for printing HANDLE args.
+
+       * main.c (handle_runtime_exceptions): Fix sprintf format strings
+       to avoid compiler warnings.
+       (open_tmpfile): Declare fd only if HAVE_FDOPEN is defined.
+       (Note: some of these fixes were submitted independently by J. Grant)
+
+2005-07-30  J. Grant <jg@jguk.org>
+
+       * prepare_w32.bat: Copy config.h.w32 to config.h if not exist.
+       * make_msvc_net2003.vcproj, make_msvc_net2003.sln: MSVC Project files.
+       * Makefile.am (EXTRA_DIST): Add MSVC Project files.
+
 2005-07-08  Paul D. Smith  <psmith@gnu.org>
 
        * config.h.W32.template: Reorder to match the standard config.h,
index c8c7cd468cb6243ed24eaa2c0d876df4608f3628..96b30759bfb050292941782c06bd8823f9faa1d7 100644 (file)
@@ -59,6 +59,7 @@ EXTRA_DIST =  README build.sh.in $(man_MANS) \
                README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
                README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
                README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
+               make_msvc_net2003.sln make_msvc_net2003.vcproj \
                readme.vms makefile.vms makefile.com config.h-vms \
                vmsdir.h vmsfunctions.c vmsify.c
 
index f0340412c3e84f208b50509321536cf975160663..c9b7bfa065c7ae7ff8155116eeeb73be67899ffd 100644 (file)
@@ -1,10 +1,22 @@
 Port of GNU make to Microsoft Windows 95/98/NT/2000/XP
 Builds natively with MSVC 2.x, 4.x, 5.x, 6.x and MSVC.NET 7.x.
+Also builds with the MinGW port of GCC 3.x (tested with GCC 3.4.2).
 
 The Windows 32-bit port of GNU make is maintained jointly by various
-people.
+people.  It was originally made by Rob Tulloh.
 
-To build with nmake on MS-Windows:
+To build with MinGW:
+
+       1. Edit config.h.W32 to your liking (especially the few
+           shell-related defines near the end).
+
+       2. Invoke build_w32.bat with the "gcc" argument:
+
+               build_w32 gcc
+
+          This produces gnumake.exe in the current directory.
+
+To build with nmake:
 
        1. Make sure cl.exe is in your %Path%. Example:
 
index 95fdd8a814da64075027bb7d6cffa4a5a0eb29c2..e0830f63276f8514980384c9b868b1e9fd0d2330 100644 (file)
@@ -1,14 +1,14 @@
-set make=gnumake\r
 if not exist config.h copy config.h.W32 config.h\r
 cd w32\subproc\r
-echo "Creating the subproc library"\r
-%ComSpec% /c build.bat\r
+@echo "Creating the subproc library"\r
+%ComSpec% /c build.bat %1\r
 cd ..\..\r
-del link.dbg link.rel\r
-del config.h\r
-copy config.h.W32 config.h\r
-echo off\r
-echo "Creating GNU make for Windows 95/NT"\r
+@echo off\r
+if exist link.dbg del link.dbg\r
+if exist link.rel del link.rel\r
+echo "Creating GNU Make for Windows 9X/NT/2K/XP"\r
+if "%1" == "gcc" GoTo GCCBuild\r
+set make=gnumake\r
 echo on\r
 if not exist .\WinDebug\nul mkdir .\WinDebug\r
 cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c\r
@@ -139,4 +139,37 @@ echo kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib sh
 link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe @link.rel\r
 if not exist .\WinRel/%make%.exe echo "WinRel build failed"\r
 if exist .\WinRel/%make%.exe echo "WinRel build succeeded!"\r
+set make=\r
+GoTo BuildEnd\r
+:GCCBuild\r
+echo on\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c main.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o\r
+gcc -mthreads -gstabs+ -ggdb3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o job.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o ar.o function.o vpath.o implicit.o glob.o fnmatch.o pathstuff.o w32_misc.o sub_proc.o w32err.o -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32\r
+:BuildEnd\r
 echo on\r
index 813610c6c80e1bc2cc58a590b55445cdc2050e3e..c70a009ba884a26d4d500b55477066449f7b9659 100644 (file)
@@ -23,6 +23,10 @@ Boston, MA 02111-1307, USA.  */
 #include "variable.h"
 #include "job.h"
 #include "commands.h"
+#ifdef WINDOWS32
+#include <windows.h>
+#include "w32err.h"
+#endif
 
 #if VMS
 # define FILE_LIST_SEPARATOR ','
@@ -420,6 +424,27 @@ fatal_error_signal (int sig)
 
   exit (10);
 #else /* not Amiga */
+#ifdef WINDOWS32
+  extern HANDLE main_thread;
+
+  /* Windows creates a sperate thread for handling Ctrl+C, so we need
+     to suspend the main thread, or else we will have race conditions
+     when both threads call reap_children.  */
+  if (main_thread)
+    {
+      DWORD susp_count = SuspendThread (main_thread);
+
+      if (susp_count != 0)
+       fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count);
+      else if (susp_count == (DWORD)-1)
+       {
+         DWORD ierr = GetLastError ();
+
+         fprintf (stderr, "SuspendThread: error %ld: %s\n",
+                  ierr, map_windows32_error_to_string (ierr));
+       }
+    }
+#endif
   handling_fatal_signal = 1;
 
   /* Set the handling for this signal to the default.
@@ -482,8 +507,11 @@ fatal_error_signal (int sig)
 #endif
 
 #ifdef WINDOWS32
-  /* Cannot call W32_kill with a pid (it needs a handle) */
-  exit (EXIT_FAILURE);
+  if (main_thread)
+    CloseHandle (main_thread);
+  /* Cannot call W32_kill with a pid (it needs a handle).  The exit
+     status of 130 emulates what happens in Bash.  */
+  exit (130);
 #else
   /* Signal the same code; this time it will really be fatal.  The signal
      will be unblocked when we return and arrive then to kill us.  */
index 32d1558408774c2db2d80a5d4afe0ea43a69859a..526aec625d29fbcfa8f65680d85d56295ffa529b 100644 (file)
@@ -5251,7 +5251,7 @@ definition of the variable.  If you defined it first with @samp{:=},
 making it a simply-expanded variable, @samp{+=} adds to that
 simply-expanded definition, and expands the new text before appending it
 to the old value just as @samp{:=} does
-(@pxref{Setting, ,Setting Variables}, for a full explanation of @samp{:=}).
+(@pxref{Setting, ,Setting Variables} for a full explanation of @samp{:=}).
 In fact,
 
 @example
index 0772739f91e6b444d085c101783c54e8ffce97a8..5bf6019ab0c3e0f8908ef3169f2c13c5f204f300 100644 (file)
@@ -1329,7 +1329,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
-    fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"),
+    fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
           GetLastError());
 
   }
@@ -1340,12 +1340,12 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
-    fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"),
+    fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
           GetLastError());
   }
 
   if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
-    fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError());
+    fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
 
   hProcess = process_init_fd(hIn, hChildOutWr, hErr);
 
diff --git a/job.c b/job.c
index 1776aca98e85a5f3f83f1aa5fc7abc5da85ab4be..1f4917558e1a829fbaebf621b6d2a5276b443946 100644 (file)
--- a/job.c
+++ b/job.c
@@ -33,10 +33,12 @@ Boston, MA 02111-1307, USA.  */
 
 /* Default shell to use.  */
 #ifdef WINDOWS32
+#include <windows.h>
 
 char *default_shell = "sh.exe";
 int no_default_sh_exe = 1;
 int batch_mode_shell = 1;
+HANDLE main_thread;
 
 #elif defined (_AMIGA)
 
@@ -444,9 +446,11 @@ extern int shell_function_pid, shell_function_completed;
 void
 reap_children (int block, int err)
 {
+#ifndef WINDOWS32
   WAIT_T status;
   /* Initially, assume we have some.  */
   int reap_more = 1;
+#endif
 
 #ifdef WAIT_NOHANG
 # define REAP_MORE reap_more
@@ -475,9 +479,14 @@ reap_children (int block, int err)
 
       if (err && block)
        {
-         /* We might block for a while, so let the user know why.  */
+          static int printed = 0;
+
+         /* We might block for a while, so let the user know why.
+             Only print this message once no matter how many jobs are left.  */
          fflush (stdout);
-         error (NILF, _("*** Waiting for unfinished jobs...."));
+          if (!printed)
+            error (NILF, _("*** Waiting for unfinished jobs...."));
+          printed = 1;
        }
 
       /* We have one less dead child to reap.  As noted in
@@ -608,23 +617,43 @@ reap_children (int block, int err)
 #ifdef WINDOWS32
           {
             HANDLE hPID;
-            int err;
+            int werr;
+            HANDLE hcTID, hcPID;
             exit_code = 0;
             exit_sig = 0;
             coredump = 0;
 
+            /* Record the thread ID of the main process, so that we
+               could suspend it in the signal handler.  */
+            if (!main_thread)
+              {
+                hcTID = GetCurrentThread ();
+                hcPID = GetCurrentProcess ();
+                if (!DuplicateHandle (hcPID, hcTID, hcPID, &main_thread, 0,
+                                      FALSE, DUPLICATE_SAME_ACCESS))
+                  {
+                    DWORD e = GetLastError ();
+                    fprintf (stderr,
+                             "Determine main thread ID (Error %ld: %s)\n",
+                             e, map_windows32_error_to_string(e));
+                  }
+                else
+                  DB (DB_VERBOSE, ("Main thread handle = 0x%08lx\n",
+                                   (unsigned long)main_thread));
+              }
+
             /* wait for anything to finish */
             hPID = process_wait_for_any();
             if (hPID)
               {
 
                 /* was an error found on this process? */
-                err = process_last_err(hPID);
+                werr = process_last_err(hPID);
 
                 /* get exit data */
                 exit_code = process_exit_code(hPID);
 
-                if (err)
+                if (werr)
                   fprintf(stderr, "make (e=%d): %s",
                           exit_code, map_windows32_error_to_string(exit_code));
 
@@ -937,7 +966,7 @@ set_child_handler_action_flags (int set_handler, int set_alarm)
 static void
 start_job_command (struct child *child)
 {
-#ifndef _AMIGA
+#if !defined(_AMIGA) && !defined(WINDOWS32)
   static int bad_stdin = -1;
 #endif
   register char *p;
@@ -1351,7 +1380,7 @@ start_job_command (struct child *child)
         int i;
         unblock_sigs();
         fprintf(stderr,
-          _("process_easy() failed failed to launch process (e=%d)\n"),
+          _("process_easy() failed failed to launch process (e=%ld)\n"),
           process_last_err(hPID));
                for (i = 0; argv[i]; i++)
                  fprintf(stderr, "%s ", argv[i]);
@@ -1968,7 +1997,7 @@ exec_command (char **argv, char **envp)
     {
       int i;
       fprintf(stderr,
-              _("process_easy() failed failed to launch process (e=%d)\n"),
+              _("process_easy() failed failed to launch process (e=%ld)\n"),
               process_last_err(hPID));
       for (i = 0; argv[i]; i++)
           fprintf(stderr, "%s ", argv[i]);
@@ -2272,7 +2301,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
 #ifdef WINDOWS32
   int slow_flag = 0;
 
-  if (no_default_sh_exe) {
+  if (!unixy_shell) {
     sh_cmds = sh_cmds_dos;
     sh_chars = sh_chars_dos;
   } else {
@@ -2449,12 +2478,11 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
            else if (p[1] != '\0')
               {
 #ifdef HAVE_DOS_PATHS
-                /* Only remove backslashes before characters special
-                   to Unixy shells.  All other backslashes are copied
-                   verbatim, since they are probably DOS-style
-                   directory separators.  This still leaves a small
-                   window for problems, but at least it should work
-                   for the vast majority of naive users.  */
+                /* Only remove backslashes before characters special to Unixy
+                   shells.  All other backslashes are copied verbatim, since
+                   they are probably DOS-style directory separators.  This
+                   still leaves a small window for problems, but at least it
+                   should work for the vast majority of naive users.  */
 
 #ifdef __MSDOS__
                 /* A dot is only special as part of the "..."
@@ -2469,7 +2497,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
 #endif
                   if (p[1] != '\\' && p[1] != '\''
                       && !isspace ((unsigned char)p[1])
-                      && (strchr (sh_chars_sh, p[1]) == 0))
+                      && strchr (sh_chars_sh, p[1]) == 0)
                     /* back up one notch, to copy the backslash */
                     --p;
 #endif  /* HAVE_DOS_PATHS */
diff --git a/main.c b/main.c
index 71e34a17a7524e4ed0081a43de3d904b2a6b3a97..37c6ef6f3b10376c9d6c48fe76384cc0b43f64af 100644 (file)
--- a/main.c
+++ b/main.c
@@ -662,14 +662,14 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
   if (! ISDB (DB_VERBOSE))
     {
       sprintf(errmsg,
-              _("%s: Interrupt/Exception caught (code = 0x%x, addr = 0x%x)\n"),
+              _("%s: Interrupt/Exception caught (code = 0x%lx, addr = 0x%lx)\n"),
               prg, exrec->ExceptionCode, exrec->ExceptionAddress);
       fprintf(stderr, errmsg);
       exit(255);
     }
 
   sprintf(errmsg,
-          _("\nUnhandled exception filter called from program %s\nExceptionCode = %x\nExceptionFlags = %x\nExceptionAddress = %x\n"),
+          _("\nUnhandled exception filter called from program %s\nExceptionCode = %lx\nExceptionFlags = %lx\nExceptionAddress = %lx\n"),
           prg, exrec->ExceptionCode, exrec->ExceptionFlags,
           exrec->ExceptionAddress);
 
@@ -677,8 +677,8 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
       && exrec->NumberParameters >= 2)
     sprintf(&errmsg[strlen(errmsg)],
             (exrec->ExceptionInformation[0]
-             ? _("Access violation: write operation at address %x\n")
-             : _("Access violation: read operation at address %x\n")),
+             ? _("Access violation: write operation at address %lx\n")
+             : _("Access violation: read operation at address %lx\n")),
             exrec->ExceptionInformation[1]);
 
   /* turn this on if we want to put stuff in the event log too */
@@ -751,7 +751,11 @@ find_and_set_default_shell (char *token)
           && !strcmpi (tokend - 4, "cmd.exe"))) {
     batch_mode_shell = 1;
     unixy_shell = 0;
-    sh_found = 0;
+    sprintf (sh_path, "%s", search_token);
+    default_shell = xstrdup (w32ify (sh_path, 0));
+    DB (DB_VERBOSE,
+        (_("find_and_set_shell setting default_shell = %s\n"), default_shell));
+    sh_found = 1;
   } else if (!no_default_sh_exe &&
              (token == NULL || !strcmp (search_token, default_shell))) {
     /* no new information, path already set or known */
@@ -838,7 +842,9 @@ extern int mkstemp PARAMS ((char *template));
 FILE *
 open_tmpfile(char **name, const char *template)
 {
+#ifdef HAVE_FDOPEN
   int fd;
+#endif
 
 #if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
 # define TEMPLATE_LEN   strlen (template)
@@ -1217,7 +1223,7 @@ main (int argc, char **argv, char **envp)
   decode_switches (argc, argv, 0);
 #ifdef WINDOWS32
   if (suspend_flag) {
-        fprintf(stderr, "%s (pid = %d)\n", argv[0], GetCurrentProcessId());
+        fprintf(stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId());
         fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]);
         Sleep(30 * 1000);
         fprintf(stderr, _("done sleep(30). Continuing.\n"));
@@ -2990,7 +2996,8 @@ die (int status)
        print_version ();
 
       /* Wait for children to die.  */
-      for (err = (status != 0); job_slots_used > 0; err = 0)
+      err = (status != 0);
+      while (job_slots_used > 0)
        reap_children (1, err);
 
       /* Let the remote job module clean up its state.  */
diff --git a/make_msvc_net2003.sln b/make_msvc_net2003.sln
new file mode 100644 (file)
index 0000000..e993896
--- /dev/null
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_msvc.net2003", "make_msvc_net2003.vcproj", "{E96B5060-3240-4723-91C9-E64F1C877A04}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+       EndProjectSection\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               Debug = Debug\r
+               Release = Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.ActiveCfg = Debug|Win32\r
+               {E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.Build.0 = Debug|Win32\r
+               {E96B5060-3240-4723-91C9-E64F1C877A04}.Release.ActiveCfg = Release|Win32\r
+               {E96B5060-3240-4723-91C9-E64F1C877A04}.Release.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/make_msvc_net2003.vcproj b/make_msvc_net2003.vcproj
new file mode 100644 (file)
index 0000000..fcf6ba8
--- /dev/null
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.10"\r
+       Name="make_msvc.net2003"\r
+       ProjectGUID="{E96B5060-3240-4723-91C9-E64F1C877A04}"\r
+       Keyword="Win32Proj">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories=".;w32/include;glob"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"\r
+                               MinimalRebuild="TRUE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               ForceConformanceInForLoopScope="TRUE"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               Detect64BitPortabilityProblems="TRUE"\r
+                               DebugInformationFormat="4"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/make_msvc.net2003.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="$(OutDir)/make_msvc.net2003.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories=".;w32/include;glob"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"\r
+                               RuntimeLibrary="0"\r
+                               ForceConformanceInForLoopScope="TRUE"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               Detect64BitPortabilityProblems="TRUE"\r
+                               DebugInformationFormat="3"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/make_msvc.net2003.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="TRUE"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               TargetMachine="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="src"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+                       <File\r
+                               RelativePath=".\ar.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\arscan.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\commands.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\default.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\dir.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\expand.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\file.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\function.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\getloadavg.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\getopt.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\getopt1.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\hash.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\implicit.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\job.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\main.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\misc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\read.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\remake.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\remote-stub.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\rule.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\signame.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\variable.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\version.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\vpath.c">\r
+                       </File>\r
+                       <Filter\r
+                               Name="w32"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath=".\w32\compat\dirent.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\subproc\misc.c">\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\pathstuff.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\subproc\sub_proc.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\subproc\w32err.c">\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="glob"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath=".\glob\fnmatch.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\glob\glob.c">\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="include"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+                       <File\r
+                               RelativePath=".\commands.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\config.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\debug.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\dep.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\filedef.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\getopt.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gettext.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\hash.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\job.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\make.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\rule.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\variable.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\vmsdir.h">\r
+                       </File>\r
+                       <Filter\r
+                               Name="w32"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath=".\w32\include\dirent.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\include\pathstuff.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\subproc\proc.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\include\sub_proc.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\w32\include\w32err.h">\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="glob"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath=".\glob\fnmatch.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\glob\glob.h">\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
index e50e5f25c4b285f8c760f130790c690210a3713e..e16b78439e69d20a17febdabd8dc8ccb21a5e337 100644 (file)
@@ -1,5 +1,6 @@
 @echo off\r
 @echo Windows32 CVS build preparation of config.h.W32 and NMakefile.\r
 if not exist config.h.W32 copy config.h.W32.template config.h.W32\r
+if not exist config.h copy config.h.W32 config.h\r
 if not exist NMakefile copy NMakefile.template NMakefile\r
 @echo Preparation complete.  Run build_w32.bat to compile and link.\r
diff --git a/read.c b/read.c
index a6e18b077ac4d6d928bdbd0dd8915af6520fced2..65a352ff833b4b274e2cd07adbf700d246284282 100644 (file)
--- a/read.c
+++ b/read.c
@@ -2064,22 +2064,19 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
                     d_ptr = &(*d_ptr)->next;
 
                   if (cmds != 0)
-                    {
-                      /* This is the rule with commands, so put its deps
-                         last. The rationale behind this is that $< expands
-                         to the first dep in the chain, and commands use $<
-                         expecting to get the dep that rule specifies.
-                         However the second expansion algorithm reverses
-                         the order thus we need to make it last here.  */
-
-                      (*d_ptr)->next = this;
-                    }
+                    /* This is the rule with commands, so put its deps
+                       last. The rationale behind this is that $< expands to
+                       the first dep in the chain, and commands use $<
+                       expecting to get the dep that rule specifies.  However
+                       the second expansion algorithm reverses the order thus
+                       we need to make it last here.  */
+                    (*d_ptr)->next = this;
                   else
                     {
                       /* This is the rule without commands. Put its
-                         dependencies at the end but before dependencies
-                         from the rule with commands (if any). This way
-                         everything appears in makefile order.  */
+                         dependencies at the end but before dependencies from
+                         the rule with commands (if any). This way everything
+                         appears in makefile order.  */
 
                       if (f->cmds != 0)
                         {
index c5583d28d2bc2cd4bfd4ae992a20d892265102a4..1e2d57c8d722d8a27ffa9270a170617bf958f426 100644 (file)
--- a/signame.c
+++ b/signame.c
@@ -239,11 +239,12 @@ strsignal (int signal)
 #  define sys_siglist _sys_siglist
 # elif HAVE_DECL___SYS_SIGLIST
 #  define sys_siglist __sys_siglist
-# endif
+# else
   static char sig_initted = 0;
 
   if (!sig_initted)
     sig_initted = signame_init ();
+# endif
 #endif
 
   if (signal > 0 || signal < NSIG)
index ee3bab547baa5754439c05f99305c6f563427448..a2050745082547b60f7e5f1d05366c072761bdd2 100644 (file)
@@ -1,3 +1,9 @@
+2005-08-07  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/features/parallelism: Add a test for a bug reported by
+       Michael Matz (matz@suse.de) in which make exits without waiting
+       for all its children in some situations during parallel builds.
+
 2005-07-08  Paul D. Smith  <psmith@gnu.org>
 
        * test_driver.pl: Reset the environment to a clean value every
index 47685392712c916153df5a9f5684c3762c96629f..c75f436dc2bb54d2d5c0b51ffc2e1e7ebc16828f 100644 (file)
@@ -83,4 +83,31 @@ all: first second
 first second: ; \@echo \$\@; $sleep_command 1; echo \$\@",
               '-j2', "first\nfirst\nsecond\nsecond");
 
+# Michael Matz <matz@suse.de> reported a bug where if make is running in
+# parallel without -k and two jobs die in a row, but not too close to each
+# other, then make will quit without waiting for the rest of the jobs to die.
+
+run_make_test("
+.PHONY: all fail.1 fail.2 fail.3 ok
+all: fail.1 ok fail.2 fail.3
+
+fail.1 fail.2 fail.3:
+       \@sleep \$(patsubst fail.%,%,\$\@)
+       \@echo Fail
+       \@exit 1
+
+ok:
+       \@sleep 4
+       \@echo Ok done",
+              '-rR -j5', 'Fail
+#MAKE#: *** [fail.1] Error 1
+#MAKE#: *** Waiting for unfinished jobs....
+Fail
+#MAKE#: *** [fail.2] Error 1
+Fail
+#MAKE#: *** [fail.3] Error 1
+Ok done',
+             512);
+
+
 1;
index d8f38453964cedaa1a893ab2639e0812bc2aacc1..2ccb26df9b7060dfe3e5f0d50986036dfad2bd1a 100644 (file)
@@ -86,9 +86,9 @@ w32ify(char *filename, int resolve)
 char *
 getcwd_fs(char* buf, int len)
 {
-       char *p;
+       char *p = getcwd(buf, len);
 
-       if (p = getcwd(buf, len)) {
+       if (p) {
                char *q = w32ify(buf, 0);
                strncpy(buf, q, len);
        }
index b68fc31fe3b9477ba5d937a1202ced5a11439a25..b057b3c0a54efd29f44e271b8ed3b477daa3edca 100644 (file)
@@ -1,3 +1,4 @@
+@if "%1" == "gcc" GoTo GCCBuild\r
 if not exist .\WinDebug\nul mkdir .\WinDebug\r
 cl.exe /nologo /MT /W4 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c misc.c\r
 cl.exe /nologo /MT /W4 /GX /Z7 /YX /Od /I .. /I . /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c sub_proc.c\r
@@ -8,3 +9,9 @@ cl.exe /nologo /MT /W4 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG
 cl.exe /nologo /MT /W4 /GX /YX /O2 /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c sub_proc.c\r
 cl.exe /nologo /MT /W4 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c w32err.c\r
 lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib  .\WinRel/misc.obj  .\WinRel/sub_proc.obj  .\WinRel/w32err.obj\r
+GoTo BuildEnd\r
+:GCCBuild\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c misc.c -o ../../w32_misc.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c sub_proc.c -o ../../sub_proc.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c w32err.c -o ../../w32err.o\r
+:BuildEnd\r
index 6e36e3744e854560a3560dddf3f24d23a3d99518..ae1a35419d1ece145b1705910baa3e19e9f1e844 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <process.h>  /* for msvc _beginthreadex, _endthreadex */
+#include <signal.h>
 #include <windows.h>
 
 #include "sub_proc.h"
@@ -522,7 +523,8 @@ process_begin(
 
                        pproc->last_err = GetLastError();
                        pproc->lerrno = E_FORK;
-                       fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line);
+                       fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
+                                exec_path ? exec_path : "NULL", command_line);
                        if (envblk) free(envblk);
                        free( command_line );
                        return(-1);
@@ -762,7 +764,13 @@ process_pipe_io(
 
                } else if (ready_hand == childhand) {
 
-                       GetExitCodeResult = GetExitCodeProcess(childhand, (DWORD*)&pproc->exit_code);
+                       DWORD ierr;
+                       GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
+                       if (ierr == CONTROL_C_EXIT) {
+                               pproc->signal = SIGINT;
+                       } else {
+                               pproc->exit_code = ierr;
+                       }
                        if (GetExitCodeResult == FALSE) {
                                pproc->last_err = GetLastError();
                                pproc->lerrno = E_SCALL;
@@ -811,6 +819,7 @@ process_file_io(
        HANDLE childhand;
        DWORD wait_return;
        BOOL GetExitCodeResult;
+        DWORD ierr;
 
        if (proc == NULL)
                pproc = process_wait_for_any_private();
@@ -854,7 +863,12 @@ process_file_io(
                goto done2;
        }
 
-       GetExitCodeResult = GetExitCodeProcess(childhand, (DWORD*)&pproc->exit_code);
+       GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
+       if (ierr == CONTROL_C_EXIT) {
+               pproc->signal = SIGINT;
+       } else {
+               pproc->exit_code = ierr;
+       }
        if (GetExitCodeResult == FALSE) {
                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
@@ -1163,7 +1177,7 @@ process_easy(
                       TRUE,
                       DUPLICATE_SAME_ACCESS) == FALSE) {
     fprintf(stderr,
-            "process_easy: DuplicateHandle(In) failed (e=%d)\n",
+            "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
             GetLastError());
     return INVALID_HANDLE_VALUE;
   }
@@ -1175,7 +1189,7 @@ process_easy(
                       TRUE,
                       DUPLICATE_SAME_ACCESS) == FALSE) {
     fprintf(stderr,
-           "process_easy: DuplicateHandle(Out) failed (e=%d)\n",
+           "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
            GetLastError());
     return INVALID_HANDLE_VALUE;
   }
@@ -1187,7 +1201,7 @@ process_easy(
                       TRUE,
                       DUPLICATE_SAME_ACCESS) == FALSE) {
     fprintf(stderr,
-            "process_easy: DuplicateHandle(Err) failed (e=%d)\n",
+            "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
             GetLastError());
     return INVALID_HANDLE_VALUE;
   }