- Fixed a bug reported by Michael Matz regarding handling of parallel

jobs after a failed job.
- Enhancements to WINDOWS32 code from Eli Zaretskii.
- Add Microsoft Project files from J. Grant.
This commit is contained in:
Paul Smith 2005-08-08 05:08:00 +00:00
parent a53903e4c3
commit b237dff775
19 changed files with 628 additions and 61 deletions

View File

@ -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> 2005-07-08 Paul D. Smith <psmith@gnu.org>
* config.h.W32.template: Reorder to match the standard config.h, * config.h.W32.template: Reorder to match the standard config.h,

View 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.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\ README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \ 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 \ readme.vms makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c vmsdir.h vmsfunctions.c vmsify.c

View File

@ -1,10 +1,22 @@
Port of GNU make to Microsoft Windows 95/98/NT/2000/XP 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. 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 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: 1. Make sure cl.exe is in your %Path%. Example:

View File

@ -1,14 +1,14 @@
set make=gnumake
if not exist config.h copy config.h.W32 config.h if not exist config.h copy config.h.W32 config.h
cd w32\subproc cd w32\subproc
echo "Creating the subproc library" @echo "Creating the subproc library"
%ComSpec% /c build.bat %ComSpec% /c build.bat %1
cd ..\.. cd ..\..
del link.dbg link.rel @echo off
del config.h if exist link.dbg del link.dbg
copy config.h.W32 config.h if exist link.rel del link.rel
echo off echo "Creating GNU Make for Windows 9X/NT/2K/XP"
echo "Creating GNU make for Windows 95/NT" if "%1" == "gcc" GoTo GCCBuild
set make=gnumake
echo on echo on
if not exist .\WinDebug\nul mkdir .\WinDebug if not exist .\WinDebug\nul mkdir .\WinDebug
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 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
@ -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 link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe @link.rel
if not exist .\WinRel/%make%.exe echo "WinRel build failed" if not exist .\WinRel/%make%.exe echo "WinRel build failed"
if exist .\WinRel/%make%.exe echo "WinRel build succeeded!" if exist .\WinRel/%make%.exe echo "WinRel build succeeded!"
set make=
GoTo BuildEnd
:GCCBuild
echo on
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c main.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o
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
:BuildEnd
echo on echo on

View File

@ -23,6 +23,10 @@ Boston, MA 02111-1307, USA. */
#include "variable.h" #include "variable.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
#ifdef WINDOWS32
#include <windows.h>
#include "w32err.h"
#endif
#if VMS #if VMS
# define FILE_LIST_SEPARATOR ',' # define FILE_LIST_SEPARATOR ','
@ -420,6 +424,27 @@ fatal_error_signal (int sig)
exit (10); exit (10);
#else /* not Amiga */ #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; handling_fatal_signal = 1;
/* Set the handling for this signal to the default. /* Set the handling for this signal to the default.
@ -482,8 +507,11 @@ fatal_error_signal (int sig)
#endif #endif
#ifdef WINDOWS32 #ifdef WINDOWS32
/* Cannot call W32_kill with a pid (it needs a handle) */ if (main_thread)
exit (EXIT_FAILURE); 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 #else
/* Signal the same code; this time it will really be fatal. The signal /* 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. */ will be unblocked when we return and arrive then to kill us. */

View 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 making it a simply-expanded variable, @samp{+=} adds to that
simply-expanded definition, and expands the new text before appending it simply-expanded definition, and expands the new text before appending it
to the old value just as @samp{:=} does 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, In fact,
@example @example

View File

@ -1329,7 +1329,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
0, 0,
TRUE, TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) { 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()); GetLastError());
} }
@ -1340,12 +1340,12 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
0, 0,
TRUE, TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) { 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()); GetLastError());
} }
if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) 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); hProcess = process_init_fd(hIn, hChildOutWr, hErr);

60
job.c
View File

@ -33,10 +33,12 @@ Boston, MA 02111-1307, USA. */
/* Default shell to use. */ /* Default shell to use. */
#ifdef WINDOWS32 #ifdef WINDOWS32
#include <windows.h>
char *default_shell = "sh.exe"; char *default_shell = "sh.exe";
int no_default_sh_exe = 1; int no_default_sh_exe = 1;
int batch_mode_shell = 1; int batch_mode_shell = 1;
HANDLE main_thread;
#elif defined (_AMIGA) #elif defined (_AMIGA)
@ -444,9 +446,11 @@ extern int shell_function_pid, shell_function_completed;
void void
reap_children (int block, int err) reap_children (int block, int err)
{ {
#ifndef WINDOWS32
WAIT_T status; WAIT_T status;
/* Initially, assume we have some. */ /* Initially, assume we have some. */
int reap_more = 1; int reap_more = 1;
#endif
#ifdef WAIT_NOHANG #ifdef WAIT_NOHANG
# define REAP_MORE reap_more # define REAP_MORE reap_more
@ -475,9 +479,14 @@ reap_children (int block, int err)
if (err && block) 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); 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 /* We have one less dead child to reap. As noted in
@ -608,23 +617,43 @@ reap_children (int block, int err)
#ifdef WINDOWS32 #ifdef WINDOWS32
{ {
HANDLE hPID; HANDLE hPID;
int err; int werr;
HANDLE hcTID, hcPID;
exit_code = 0; exit_code = 0;
exit_sig = 0; exit_sig = 0;
coredump = 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 */ /* wait for anything to finish */
hPID = process_wait_for_any(); hPID = process_wait_for_any();
if (hPID) if (hPID)
{ {
/* was an error found on this process? */ /* was an error found on this process? */
err = process_last_err(hPID); werr = process_last_err(hPID);
/* get exit data */ /* get exit data */
exit_code = process_exit_code(hPID); exit_code = process_exit_code(hPID);
if (err) if (werr)
fprintf(stderr, "make (e=%d): %s", fprintf(stderr, "make (e=%d): %s",
exit_code, map_windows32_error_to_string(exit_code)); 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 static void
start_job_command (struct child *child) start_job_command (struct child *child)
{ {
#ifndef _AMIGA #if !defined(_AMIGA) && !defined(WINDOWS32)
static int bad_stdin = -1; static int bad_stdin = -1;
#endif #endif
register char *p; register char *p;
@ -1351,7 +1380,7 @@ start_job_command (struct child *child)
int i; int i;
unblock_sigs(); unblock_sigs();
fprintf(stderr, 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)); process_last_err(hPID));
for (i = 0; argv[i]; i++) for (i = 0; argv[i]; i++)
fprintf(stderr, "%s ", argv[i]); fprintf(stderr, "%s ", argv[i]);
@ -1968,7 +1997,7 @@ exec_command (char **argv, char **envp)
{ {
int i; int i;
fprintf(stderr, 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)); process_last_err(hPID));
for (i = 0; argv[i]; i++) for (i = 0; argv[i]; i++)
fprintf(stderr, "%s ", argv[i]); fprintf(stderr, "%s ", argv[i]);
@ -2272,7 +2301,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
#ifdef WINDOWS32 #ifdef WINDOWS32
int slow_flag = 0; int slow_flag = 0;
if (no_default_sh_exe) { if (!unixy_shell) {
sh_cmds = sh_cmds_dos; sh_cmds = sh_cmds_dos;
sh_chars = sh_chars_dos; sh_chars = sh_chars_dos;
} else { } else {
@ -2449,12 +2478,11 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
else if (p[1] != '\0') else if (p[1] != '\0')
{ {
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
/* Only remove backslashes before characters special /* Only remove backslashes before characters special to Unixy
to Unixy shells. All other backslashes are copied shells. All other backslashes are copied verbatim, since
verbatim, since they are probably DOS-style they are probably DOS-style directory separators. This
directory separators. This still leaves a small still leaves a small window for problems, but at least it
window for problems, but at least it should work should work for the vast majority of naive users. */
for the vast majority of naive users. */
#ifdef __MSDOS__ #ifdef __MSDOS__
/* A dot is only special as part of the "..." /* A dot is only special as part of the "..."
@ -2469,7 +2497,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
#endif #endif
if (p[1] != '\\' && p[1] != '\'' if (p[1] != '\\' && p[1] != '\''
&& !isspace ((unsigned char)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 */ /* back up one notch, to copy the backslash */
--p; --p;
#endif /* HAVE_DOS_PATHS */ #endif /* HAVE_DOS_PATHS */

21
main.c
View File

@ -662,14 +662,14 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
if (! ISDB (DB_VERBOSE)) if (! ISDB (DB_VERBOSE))
{ {
sprintf(errmsg, 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); prg, exrec->ExceptionCode, exrec->ExceptionAddress);
fprintf(stderr, errmsg); fprintf(stderr, errmsg);
exit(255); exit(255);
} }
sprintf(errmsg, 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, prg, exrec->ExceptionCode, exrec->ExceptionFlags,
exrec->ExceptionAddress); exrec->ExceptionAddress);
@ -677,8 +677,8 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
&& exrec->NumberParameters >= 2) && exrec->NumberParameters >= 2)
sprintf(&errmsg[strlen(errmsg)], sprintf(&errmsg[strlen(errmsg)],
(exrec->ExceptionInformation[0] (exrec->ExceptionInformation[0]
? _("Access violation: write operation at address %x\n") ? _("Access violation: write operation at address %lx\n")
: _("Access violation: read operation at address %x\n")), : _("Access violation: read operation at address %lx\n")),
exrec->ExceptionInformation[1]); exrec->ExceptionInformation[1]);
/* turn this on if we want to put stuff in the event log too */ /* 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"))) { && !strcmpi (tokend - 4, "cmd.exe"))) {
batch_mode_shell = 1; batch_mode_shell = 1;
unixy_shell = 0; 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 && } else if (!no_default_sh_exe &&
(token == NULL || !strcmp (search_token, default_shell))) { (token == NULL || !strcmp (search_token, default_shell))) {
/* no new information, path already set or known */ /* no new information, path already set or known */
@ -838,7 +842,9 @@ extern int mkstemp PARAMS ((char *template));
FILE * FILE *
open_tmpfile(char **name, const char *template) open_tmpfile(char **name, const char *template)
{ {
#ifdef HAVE_FDOPEN
int fd; int fd;
#endif
#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP #if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
# define TEMPLATE_LEN strlen (template) # define TEMPLATE_LEN strlen (template)
@ -1217,7 +1223,7 @@ main (int argc, char **argv, char **envp)
decode_switches (argc, argv, 0); decode_switches (argc, argv, 0);
#ifdef WINDOWS32 #ifdef WINDOWS32
if (suspend_flag) { 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]); fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]);
Sleep(30 * 1000); Sleep(30 * 1000);
fprintf(stderr, _("done sleep(30). Continuing.\n")); fprintf(stderr, _("done sleep(30). Continuing.\n"));
@ -2990,7 +2996,8 @@ die (int status)
print_version (); print_version ();
/* Wait for children to die. */ /* 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); reap_children (1, err);
/* Let the remote job module clean up its state. */ /* Let the remote job module clean up its state. */

21
make_msvc_net2003.sln Normal file
View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_msvc.net2003", "make_msvc_net2003.vcproj", "{E96B5060-3240-4723-91C9-E64F1C877A04}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.ActiveCfg = Debug|Win32
{E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.Build.0 = Debug|Win32
{E96B5060-3240-4723-91C9-E64F1C877A04}.Release.ActiveCfg = Release|Win32
{E96B5060-3240-4723-91C9-E64F1C877A04}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

309
make_msvc_net2003.vcproj Normal file
View File

@ -0,0 +1,309 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="make_msvc.net2003"
ProjectGUID="{E96B5060-3240-4723-91C9-E64F1C877A04}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".;w32/include;glob"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/make_msvc.net2003.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/make_msvc.net2003.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".;w32/include;glob"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"
RuntimeLibrary="0"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/make_msvc.net2003.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="src"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\ar.c">
</File>
<File
RelativePath=".\arscan.c">
</File>
<File
RelativePath=".\commands.c">
</File>
<File
RelativePath=".\default.c">
</File>
<File
RelativePath=".\dir.c">
</File>
<File
RelativePath=".\expand.c">
</File>
<File
RelativePath=".\file.c">
</File>
<File
RelativePath=".\function.c">
</File>
<File
RelativePath=".\getloadavg.c">
</File>
<File
RelativePath=".\getopt.c">
</File>
<File
RelativePath=".\getopt1.c">
</File>
<File
RelativePath=".\hash.c">
</File>
<File
RelativePath=".\implicit.c">
</File>
<File
RelativePath=".\job.c">
</File>
<File
RelativePath=".\main.c">
</File>
<File
RelativePath=".\misc.c">
</File>
<File
RelativePath=".\read.c">
</File>
<File
RelativePath=".\remake.c">
</File>
<File
RelativePath=".\remote-stub.c">
</File>
<File
RelativePath=".\rule.c">
</File>
<File
RelativePath=".\signame.c">
</File>
<File
RelativePath=".\variable.c">
</File>
<File
RelativePath=".\version.c">
</File>
<File
RelativePath=".\vpath.c">
</File>
<Filter
Name="w32"
Filter="">
<File
RelativePath=".\w32\compat\dirent.c">
</File>
<File
RelativePath=".\w32\subproc\misc.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
</File>
<File
RelativePath=".\w32\pathstuff.c">
</File>
<File
RelativePath=".\w32\subproc\sub_proc.c">
</File>
<File
RelativePath=".\w32\subproc\w32err.c">
</File>
</Filter>
<Filter
Name="glob"
Filter="">
<File
RelativePath=".\glob\fnmatch.c">
</File>
<File
RelativePath=".\glob\glob.c">
</File>
</Filter>
</Filter>
<Filter
Name="include"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\commands.h">
</File>
<File
RelativePath=".\config.h">
</File>
<File
RelativePath=".\debug.h">
</File>
<File
RelativePath=".\dep.h">
</File>
<File
RelativePath=".\filedef.h">
</File>
<File
RelativePath=".\getopt.h">
</File>
<File
RelativePath=".\gettext.h">
</File>
<File
RelativePath=".\hash.h">
</File>
<File
RelativePath=".\job.h">
</File>
<File
RelativePath=".\make.h">
</File>
<File
RelativePath=".\rule.h">
</File>
<File
RelativePath=".\variable.h">
</File>
<File
RelativePath=".\vmsdir.h">
</File>
<Filter
Name="w32"
Filter="">
<File
RelativePath=".\w32\include\dirent.h">
</File>
<File
RelativePath=".\w32\include\pathstuff.h">
</File>
<File
RelativePath=".\w32\subproc\proc.h">
</File>
<File
RelativePath=".\w32\include\sub_proc.h">
</File>
<File
RelativePath=".\w32\include\w32err.h">
</File>
</Filter>
<Filter
Name="glob"
Filter="">
<File
RelativePath=".\glob\fnmatch.h">
</File>
<File
RelativePath=".\glob\glob.h">
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,5 +1,6 @@
@echo off @echo off
@echo Windows32 CVS build preparation of config.h.W32 and NMakefile. @echo Windows32 CVS build preparation of config.h.W32 and NMakefile.
if not exist config.h.W32 copy config.h.W32.template config.h.W32 if not exist config.h.W32 copy config.h.W32.template config.h.W32
if not exist config.h copy config.h.W32 config.h
if not exist NMakefile copy NMakefile.template NMakefile if not exist NMakefile copy NMakefile.template NMakefile
@echo Preparation complete. Run build_w32.bat to compile and link. @echo Preparation complete. Run build_w32.bat to compile and link.

23
read.c
View File

@ -2064,22 +2064,19 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
d_ptr = &(*d_ptr)->next; d_ptr = &(*d_ptr)->next;
if (cmds != 0) if (cmds != 0)
{ /* This is the rule with commands, so put its deps
/* This is the rule with commands, so put its deps last. The rationale behind this is that $< expands to
last. The rationale behind this is that $< expands the first dep in the chain, and commands use $<
to the first dep in the chain, and commands use $< expecting to get the dep that rule specifies. However
expecting to get the dep that rule specifies. the second expansion algorithm reverses the order thus
However the second expansion algorithm reverses we need to make it last here. */
the order thus we need to make it last here. */ (*d_ptr)->next = this;
(*d_ptr)->next = this;
}
else else
{ {
/* This is the rule without commands. Put its /* This is the rule without commands. Put its
dependencies at the end but before dependencies dependencies at the end but before dependencies from
from the rule with commands (if any). This way the rule with commands (if any). This way everything
everything appears in makefile order. */ appears in makefile order. */
if (f->cmds != 0) if (f->cmds != 0)
{ {

View File

@ -239,11 +239,12 @@ strsignal (int signal)
# define sys_siglist _sys_siglist # define sys_siglist _sys_siglist
# elif HAVE_DECL___SYS_SIGLIST # elif HAVE_DECL___SYS_SIGLIST
# define sys_siglist __sys_siglist # define sys_siglist __sys_siglist
# endif # else
static char sig_initted = 0; static char sig_initted = 0;
if (!sig_initted) if (!sig_initted)
sig_initted = signame_init (); sig_initted = signame_init ();
# endif
#endif #endif
if (signal > 0 || signal < NSIG) if (signal > 0 || signal < NSIG)

View 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> 2005-07-08 Paul D. Smith <psmith@gnu.org>
* test_driver.pl: Reset the environment to a clean value every * test_driver.pl: Reset the environment to a clean value every

View File

@ -83,4 +83,31 @@ all: first second
first second: ; \@echo \$\@; $sleep_command 1; echo \$\@", first second: ; \@echo \$\@; $sleep_command 1; echo \$\@",
'-j2', "first\nfirst\nsecond\nsecond"); '-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; 1;

View File

@ -86,9 +86,9 @@ w32ify(char *filename, int resolve)
char * char *
getcwd_fs(char* buf, int len) 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); char *q = w32ify(buf, 0);
strncpy(buf, q, len); strncpy(buf, q, len);
} }

View File

@ -1,3 +1,4 @@
@if "%1" == "gcc" GoTo GCCBuild
if not exist .\WinDebug\nul mkdir .\WinDebug if not exist .\WinDebug\nul mkdir .\WinDebug
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 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
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 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
@ -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 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
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 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
lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib .\WinRel/misc.obj .\WinRel/sub_proc.obj .\WinRel/w32err.obj lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib .\WinRel/misc.obj .\WinRel/sub_proc.obj .\WinRel/w32err.obj
GoTo BuildEnd
:GCCBuild
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c misc.c -o ../../w32_misc.o
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c sub_proc.c -o ../../sub_proc.o
gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c w32err.c -o ../../w32err.o
:BuildEnd

View File

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <process.h> /* for msvc _beginthreadex, _endthreadex */ #include <process.h> /* for msvc _beginthreadex, _endthreadex */
#include <signal.h>
#include <windows.h> #include <windows.h>
#include "sub_proc.h" #include "sub_proc.h"
@ -522,7 +523,8 @@ process_begin(
pproc->last_err = GetLastError(); pproc->last_err = GetLastError();
pproc->lerrno = E_FORK; 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); if (envblk) free(envblk);
free( command_line ); free( command_line );
return(-1); return(-1);
@ -762,7 +764,13 @@ process_pipe_io(
} else if (ready_hand == childhand) { } 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) { if (GetExitCodeResult == FALSE) {
pproc->last_err = GetLastError(); pproc->last_err = GetLastError();
pproc->lerrno = E_SCALL; pproc->lerrno = E_SCALL;
@ -811,6 +819,7 @@ process_file_io(
HANDLE childhand; HANDLE childhand;
DWORD wait_return; DWORD wait_return;
BOOL GetExitCodeResult; BOOL GetExitCodeResult;
DWORD ierr;
if (proc == NULL) if (proc == NULL)
pproc = process_wait_for_any_private(); pproc = process_wait_for_any_private();
@ -854,7 +863,12 @@ process_file_io(
goto done2; 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) { if (GetExitCodeResult == FALSE) {
pproc->last_err = GetLastError(); pproc->last_err = GetLastError();
pproc->lerrno = E_SCALL; pproc->lerrno = E_SCALL;
@ -1163,7 +1177,7 @@ process_easy(
TRUE, TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) { DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr, fprintf(stderr,
"process_easy: DuplicateHandle(In) failed (e=%d)\n", "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
GetLastError()); GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@ -1175,7 +1189,7 @@ process_easy(
TRUE, TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) { DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr, fprintf(stderr,
"process_easy: DuplicateHandle(Out) failed (e=%d)\n", "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
GetLastError()); GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@ -1187,7 +1201,7 @@ process_easy(
TRUE, TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) { DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr, fprintf(stderr,
"process_easy: DuplicateHandle(Err) failed (e=%d)\n", "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
GetLastError()); GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }