summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog75
-rw-r--r--Makefile.am1
-rw-r--r--README.W32.template16
-rw-r--r--build_w32.bat49
-rw-r--r--commands.c32
-rw-r--r--doc/make.texi2
-rw-r--r--function.c6
-rw-r--r--job.c60
-rw-r--r--main.c21
-rw-r--r--make_msvc_net2003.sln21
-rw-r--r--make_msvc_net2003.vcproj309
-rw-r--r--prepare_w32.bat1
-rw-r--r--read.c23
-rw-r--r--signame.c3
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/scripts/features/parallelism27
-rw-r--r--w32/pathstuff.c4
-rw-r--r--w32/subproc/build.bat7
-rw-r--r--w32/subproc/sub_proc.c26
19 files changed, 628 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 2a22cbb..4d2c55b 100644
--- 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,
diff --git a/Makefile.am b/Makefile.am
index c8c7cd4..96b3075 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/README.W32.template b/README.W32.template
index f034041..c9b7bfa 100644
--- a/README.W32.template
+++ b/README.W32.template
@@ -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:
diff --git a/build_w32.bat b/build_w32.bat
index 95fdd8a..e0830f6 100644
--- a/build_w32.bat
+++ b/build_w32.bat
@@ -1,14 +1,14 @@
-set make=gnumake
if not exist config.h copy config.h.W32 config.h
cd w32\subproc
-echo "Creating the subproc library"
-%ComSpec% /c build.bat
+@echo "Creating the subproc library"
+%ComSpec% /c build.bat %1
cd ..\..
-del link.dbg link.rel
-del config.h
-copy config.h.W32 config.h
-echo off
-echo "Creating GNU make for Windows 95/NT"
+@echo off
+if exist link.dbg del link.dbg
+if exist link.rel del link.rel
+echo "Creating GNU Make for Windows 9X/NT/2K/XP"
+if "%1" == "gcc" GoTo GCCBuild
+set make=gnumake
echo on
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
@@ -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
if not exist .\WinRel/%make%.exe echo "WinRel build failed"
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
diff --git a/commands.c b/commands.c
index 813610c..c70a009 100644
--- a/commands.c
+++ b/commands.c
@@ -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. */
diff --git a/doc/make.texi b/doc/make.texi
index 32d1558..526aec6 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -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
diff --git a/function.c b/function.c
index 0772739..5bf6019 100644
--- a/function.c
+++ b/function.c
@@ -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 1776aca..1f49175 100644
--- 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 71e34a1..37c6ef6 100644
--- 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
index 0000000..e993896
--- /dev/null
+++ b/make_msvc_net2003.sln
@@ -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
diff --git a/make_msvc_net2003.vcproj b/make_msvc_net2003.vcproj
new file mode 100644
index 0000000..fcf6ba8
--- /dev/null
+++ b/make_msvc_net2003.vcproj
@@ -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>
diff --git a/prepare_w32.bat b/prepare_w32.bat
index e50e5f2..e16b784 100644
--- a/prepare_w32.bat
+++ b/prepare_w32.bat
@@ -1,5 +1,6 @@
@echo off
@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 copy config.h.W32 config.h
if not exist NMakefile copy NMakefile.template NMakefile
@echo Preparation complete. Run build_w32.bat to compile and link.
diff --git a/read.c b/read.c
index a6e18b0..65a352f 100644
--- 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)
{
diff --git a/signame.c b/signame.c
index c5583d2..1e2d57c 100644
--- 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)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ee3bab5..a205074 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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
diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism
index 4768539..c75f436 100644
--- a/tests/scripts/features/parallelism
+++ b/tests/scripts/features/parallelism
@@ -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;
diff --git a/w32/pathstuff.c b/w32/pathstuff.c
index d8f3845..2ccb26d 100644
--- a/w32/pathstuff.c
+++ b/w32/pathstuff.c
@@ -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);
}
diff --git a/w32/subproc/build.bat b/w32/subproc/build.bat
index b68fc31..b057b3c 100644
--- a/w32/subproc/build.bat
+++ b/w32/subproc/build.bat
@@ -1,3 +1,4 @@
+@if "%1" == "gcc" GoTo GCCBuild
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 /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 /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
+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
diff --git a/w32/subproc/sub_proc.c b/w32/subproc/sub_proc.c
index 6e36e37..ae1a354 100644
--- a/w32/subproc/sub_proc.c
+++ b/w32/subproc/sub_proc.c
@@ -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;
}