- Fix Savannah bug #18124

- Fix Savannah bug #17521
- Fix Savannah bug #16401
- Fix Savannah bug #16469
- Fix Savannah bug #16473
This commit is contained in:
Paul Smith 2009-06-09 15:35:38 +00:00
parent a72bff7cb3
commit d4ee001292
11 changed files with 161 additions and 74 deletions

View File

@ -1,5 +1,26 @@
2009-06-09 Paul Smith <psmith@gnu.org>
* main.c (clean_jobserver): Clear the jobserver_fds options and
set job_slots to the default when we clean up.
(define_makeflags): Return the new MAKEFLAGS value.
(main): Reset MAKEFLAGS in the environment when we re-exec.
Fixes Savannah bug #18124.
2009-06-08 Paul Smith <psmith@gnu.org>
* read.c (eval): Collapse continuations post-semicolon on target-
specific variables. Fixes Savannah bug #17521.
2009-06-07 Paul Smith <psmith@gnu.org> 2009-06-07 Paul Smith <psmith@gnu.org>
* job.c (reap_children): For older systems without waitpid() (are
there any of these left?) run wait(2) inside EINTRLOOP to handle
EINTR errors. Fixes Savannah bug #16401.
* (various): Debug message cleanup. Fixes Savannah bug #16469.
* main.c: Fix bsd_signal() typedef. Fixes Savannah bug #16473.
* file.c (snap_deps): Set SNAPPED_DEPS at the start of snapping, * file.c (snap_deps): Set SNAPPED_DEPS at the start of snapping,
not the end, to catch second expansion $(eval ...) defining new not the end, to catch second expansion $(eval ...) defining new
target/prereq relationships during snap_deps. target/prereq relationships during snap_deps.

View File

@ -66,7 +66,7 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
&bufdesc.dsc$w_length, 0); &bufdesc.dsc$w_length, 0);
if (! (status & 1)) if (! (status & 1))
{ {
error (NILF, _("lbr$set_module failed to extract module info, status = %d"), error (NILF, _("lbr$set_module() failed to extract module info, status = %d"),
status); status);
lbr$close (&VMS_lib_idx); lbr$close (&VMS_lib_idx);
@ -151,7 +151,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
if (! (status & 1)) if (! (status & 1))
{ {
error (NILF, _("lbr$ini_control failed with status = %d"),status); error (NILF, _("lbr$ini_control() failed with status = %d"), status);
return -2; return -2;
} }

View File

@ -1461,7 +1461,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=%ld)\n"), fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
GetLastError()); GetLastError());
} }
@ -1472,7 +1472,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(Err) failed (e=%ld)\n"), fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
GetLastError()); GetLastError());
} }
@ -1482,7 +1482,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
hProcess = process_init_fd(hIn, hChildOutWr, hErr); hProcess = process_init_fd(hIn, hChildOutWr, hErr);
if (!hProcess) if (!hProcess)
fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n")); fatal (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
/* make sure that CreateProcess() has Path it needs */ /* make sure that CreateProcess() has Path it needs */
sync_Path_environment(); sync_Path_environment();

4
job.c
View File

@ -551,7 +551,7 @@ reap_children (int block, int err)
pid = WAIT_NOHANG (&status); pid = WAIT_NOHANG (&status);
else else
#endif #endif
pid = wait (&status); EINTRLOOP(pid, wait (&status));
#endif /* !VMS */ #endif /* !VMS */
} }
else else
@ -2028,7 +2028,7 @@ exec_command (char **argv, char **envp)
{ {
int i; int i;
fprintf(stderr, fprintf(stderr,
_("process_easy() failed failed to launch process (e=%ld)\n"), _("process_easy() 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]);

153
main.c
View File

@ -80,7 +80,7 @@ static void print_data_base (void);
static void print_version (void); static void print_version (void);
static void decode_switches (int argc, char **argv, int env); static void decode_switches (int argc, char **argv, int env);
static void decode_env_switches (char *envar, unsigned int len); static void decode_env_switches (char *envar, unsigned int len);
static void define_makeflags (int all, int makefile); static const char *define_makeflags (int all, int makefile);
static char *quote_for_env (char *out, const char *in); static char *quote_for_env (char *out, const char *in);
static void initialize_global_hash_tables (void); static void initialize_global_hash_tables (void);
@ -516,7 +516,7 @@ int fatal_signal_mask;
# if !defined HAVE_SIGACTION # if !defined HAVE_SIGACTION
# define bsd_signal signal # define bsd_signal signal
# else # else
typedef RETSIGTYPE (*bsd_signal_ret_t) (); typedef RETSIGTYPE (*bsd_signal_ret_t) (int);
static bsd_signal_ret_t static bsd_signal_ret_t
bsd_signal (int sig, bsd_signal_ret_t func) bsd_signal (int sig, bsd_signal_ret_t func)
@ -767,8 +767,8 @@ find_and_set_default_shell (const char *token)
unixy_shell = 0; unixy_shell = 0;
sprintf (sh_path, "%s", search_token); sprintf (sh_path, "%s", search_token);
default_shell = xstrdup (w32ify (sh_path, 0)); default_shell = xstrdup (w32ify (sh_path, 0));
DB (DB_VERBOSE, DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
(_("find_and_set_shell setting default_shell = %s\n"), default_shell)); default_shell));
sh_found = 1; 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))) {
@ -778,8 +778,8 @@ find_and_set_default_shell (const char *token)
/* search token path was found */ /* search token path was found */
sprintf (sh_path, "%s", search_token); sprintf (sh_path, "%s", search_token);
default_shell = xstrdup (w32ify (sh_path, 0)); default_shell = xstrdup (w32ify (sh_path, 0));
DB (DB_VERBOSE, DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
(_("find_and_set_shell setting default_shell = %s\n"), default_shell)); default_shell));
sh_found = 1; sh_found = 1;
} else { } else {
char *p; char *p;
@ -820,7 +820,7 @@ find_and_set_default_shell (const char *token)
if (sh_found) if (sh_found)
DB (DB_VERBOSE, DB (DB_VERBOSE,
(_("find_and_set_shell path search set default_shell = %s\n"), (_("find_and_set_shell() path search set default_shell = %s\n"),
default_shell)); default_shell));
} }
} }
@ -1663,60 +1663,60 @@ main (int argc, char **argv, char **envp)
/* If the jobserver-fds option is seen, make sure that -j is reasonable. */ /* If the jobserver-fds option is seen, make sure that -j is reasonable. */
if (jobserver_fds) if (jobserver_fds)
{ {
const char *cp; const char *cp;
unsigned int ui; unsigned int ui;
for (ui=1; ui < jobserver_fds->idx; ++ui) for (ui=1; ui < jobserver_fds->idx; ++ui)
if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui])) if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
fatal (NILF, _("internal error: multiple --jobserver-fds options")); fatal (NILF, _("internal error: multiple --jobserver-fds options"));
/* Now parse the fds string and make sure it has the proper format. */ /* Now parse the fds string and make sure it has the proper format. */
cp = jobserver_fds->list[0]; cp = jobserver_fds->list[0];
if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2) if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
fatal (NILF, fatal (NILF,
_("internal error: invalid --jobserver-fds string `%s'"), cp); _("internal error: invalid --jobserver-fds string `%s'"), cp);
DB (DB_JOBS, DB (DB_JOBS,
(_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1])); (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
/* The combination of a pipe + !job_slots means we're using the /* The combination of a pipe + !job_slots means we're using the
jobserver. If !job_slots and we don't have a pipe, we can start jobserver. If !job_slots and we don't have a pipe, we can start
infinite jobs. If we see both a pipe and job_slots >0 that means the infinite jobs. If we see both a pipe and job_slots >0 that means the
user set -j explicitly. This is broken; in this case obey the user user set -j explicitly. This is broken; in this case obey the user
(ignore the jobserver pipe for this make) but print a message. */ (ignore the jobserver pipe for this make) but print a message. */
if (job_slots > 0)
error (NILF,
_("warning: -jN forced in submake: disabling jobserver mode."));
/* Create a duplicate pipe, that will be closed in the SIGCHLD
handler. If this fails with EBADF, the parent has closed the pipe
on us because it didn't think we were a submake. If so, print a
warning then default to -j1. */
else if ((job_rfd = dup (job_fds[0])) < 0)
{
if (errno != EBADF)
pfatal_with_name (_("dup jobserver"));
if (job_slots > 0)
error (NILF, error (NILF,
_("warning: jobserver unavailable: using -j1. Add `+' to parent make rule.")); _("warning: -jN forced in submake: disabling jobserver mode."));
job_slots = 1;
}
if (job_slots > 0) /* Create a duplicate pipe, that will be closed in the SIGCHLD
{ handler. If this fails with EBADF, the parent has closed the pipe
close (job_fds[0]); on us because it didn't think we were a submake. If so, print a
close (job_fds[1]); warning then default to -j1. */
job_fds[0] = job_fds[1] = -1;
free (jobserver_fds->list); else if ((job_rfd = dup (job_fds[0])) < 0)
free (jobserver_fds); {
jobserver_fds = 0; if (errno != EBADF)
} pfatal_with_name (_("dup jobserver"));
}
error (NILF,
_("warning: jobserver unavailable: using -j1. Add `+' to parent make rule."));
job_slots = 1;
}
if (job_slots > 0)
{
close (job_fds[0]);
close (job_fds[1]);
job_fds[0] = job_fds[1] = -1;
free (jobserver_fds->list);
free (jobserver_fds);
jobserver_fds = 0;
}
}
/* If we have >1 slot but no jobserver-fds, then we're a top-level make. /* If we have >1 slot but no jobserver-fds, then we're a top-level make.
Set up the pipe and install the fds option for our children. */ Set up the pipe and install the fds option for our children. */
@ -1834,8 +1834,8 @@ main (int argc, char **argv, char **envp)
FILE_TIMESTAMP *makefile_mtimes = 0; FILE_TIMESTAMP *makefile_mtimes = 0;
unsigned int mm_idx = 0; unsigned int mm_idx = 0;
char **nargv = argv; char **nargv;
int nargc = argc; int nargc;
int orig_db_level = db_level; int orig_db_level = db_level;
int status; int status;
@ -2004,8 +2004,7 @@ main (int argc, char **argv, char **envp)
for (i = 1; i < argc; ++i) for (i = 1; i < argc; ++i)
if (strneq (argv[i], "-f", 2)) /* XXX */ if (strneq (argv[i], "-f", 2)) /* XXX */
{ {
char *p = &argv[i][2]; if (argv[i][2] == '\0')
if (*p == '\0')
/* This cast is OK since we never modify argv. */ /* This cast is OK since we never modify argv. */
argv[++i] = (char *) makefiles->list[j]; argv[++i] = (char *) makefiles->list[j];
else else
@ -2015,6 +2014,7 @@ main (int argc, char **argv, char **envp)
} }
/* Add -o option for the stdin temporary file, if necessary. */ /* Add -o option for the stdin temporary file, if necessary. */
nargc = argc;
if (stdin_nm) if (stdin_nm)
{ {
nargv = xmalloc ((nargc + 2) * sizeof (char *)); nargv = xmalloc ((nargc + 2) * sizeof (char *));
@ -2022,6 +2022,8 @@ main (int argc, char **argv, char **envp)
nargv[nargc++] = xstrdup (concat ("-o", stdin_nm, "")); nargv[nargc++] = xstrdup (concat ("-o", stdin_nm, ""));
nargv[nargc] = 0; nargv[nargc] = 0;
} }
else
nargv = argv;
if (directories != 0 && directories->idx > 0) if (directories != 0 && directories->idx > 0)
{ {
@ -2039,6 +2041,14 @@ main (int argc, char **argv, char **envp)
++restarts; ++restarts;
/* Reset makeflags in case they were changed. */
{
const char *pv = define_makeflags (1, 1);
char *p = alloca (sizeof ("MAKEFLAGS=") + strlen (pv) + 1);
sprintf (p, "MAKEFLAGS=%s", pv);
putenv (p);
}
if (ISDB (DB_BASIC)) if (ISDB (DB_BASIC))
{ {
char **p; char **p;
@ -2691,7 +2701,7 @@ quote_for_env (char *out, const char *in)
command switches. Include options with args if ALL is nonzero. command switches. Include options with args if ALL is nonzero.
Don't include options with the `no_makefile' flag set if MAKEFILE. */ Don't include options with the `no_makefile' flag set if MAKEFILE. */
static void static const char *
define_makeflags (int all, int makefile) define_makeflags (int all, int makefile)
{ {
static const char ref[] = "$(MAKEOVERRIDES)"; static const char ref[] = "$(MAKEOVERRIDES)";
@ -2931,13 +2941,12 @@ define_makeflags (int all, int makefile)
/* Terminate the string. */ /* Terminate the string. */
*p = '\0'; *p = '\0';
v = define_variable ("MAKEFLAGS", 9, /* If there are switches, omit the leading dash unless it is a single long
/* If there are switches, omit the leading dash option with two leading dashes. */
unless it is a single long option with two if (flagstring[0] == '-' && flagstring[1] != '-')
leading dashes. */ ++flagstring;
&flagstring[(flagstring[0] == '-'
&& flagstring[1] != '-') v = define_variable ("MAKEFLAGS", 9, flagstring,
? 1 : 0],
/* This used to use o_env, but that lost when a /* This used to use o_env, but that lost when a
makefile defined MAKEFLAGS. Makefiles set makefile defined MAKEFLAGS. Makefiles set
MAKEFLAGS to add switches, but we still want MAKEFLAGS to add switches, but we still want
@ -2945,11 +2954,14 @@ define_makeflags (int all, int makefile)
switches. Of course, an override or command switches. Of course, an override or command
definition will still take precedence. */ definition will still take precedence. */
o_file, 1); o_file, 1);
if (! all) if (! all)
/* The first time we are called, set MAKEFLAGS to always be exported. /* The first time we are called, set MAKEFLAGS to always be exported.
We should not do this again on the second call, because that is We should not do this again on the second call, because that is
after reading makefiles which might have done `unexport MAKEFLAGS'. */ after reading makefiles which might have done `unexport MAKEFLAGS'. */
v->export = v_export; v->export = v_export;
return v->value;
} }
/* Print version information. */ /* Print version information. */
@ -2978,7 +2990,7 @@ print_version (void)
year, and none of the rest of it should be translated (including the year, and none of the rest of it should be translated (including the
word "Copyright", so it hardly seems worth it. */ word "Copyright", so it hardly seems worth it. */
printf ("%sCopyright (C) 2007 Free Software Foundation, Inc.\n", precede); printf ("%sCopyright (C) 2009 Free Software Foundation, Inc.\n", precede);
printf (_("%sLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\ printf (_("%sLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
%sThis is free software: you are free to change and redistribute it.\n\ %sThis is free software: you are free to change and redistribute it.\n\
@ -3060,6 +3072,17 @@ clean_jobserver (int status)
tcnt, master_job_slots); tcnt, master_job_slots);
close (job_fds[0]); close (job_fds[0]);
/* Clean out jobserver_fds so we don't pass this information to any
sub-makes. Also reset job_slots since it will be put on the command
line, not in MAKEFLAGS. */
job_slots = default_job_slots;
if (jobserver_fds)
{
free (jobserver_fds->list);
free (jobserver_fds);
jobserver_fds = 0;
}
} }
} }

1
read.c
View File

@ -1061,6 +1061,7 @@ eval (struct ebuffer *ebuf, int set_default)
{ {
unsigned int l = p - variable_buffer; unsigned int l = p - variable_buffer;
*(--semip) = ';'; *(--semip) = ';';
collapse_continuations (semip);
variable_buffer_output (p2 + strlen (p2), variable_buffer_output (p2 + strlen (p2),
semip, strlen (semip)+1); semip, strlen (semip)+1);
p = variable_buffer + l; p = variable_buffer + l;

2
rule.c
View File

@ -541,7 +541,7 @@ print_rule_data_base (void)
/* This can happen if a fatal error was detected while reading the /* This can happen if a fatal error was detected while reading the
makefiles and thus count_implicit_rule_limits wasn't called yet. */ makefiles and thus count_implicit_rule_limits wasn't called yet. */
if (num_pattern_rules != 0) if (num_pattern_rules != 0)
fatal (NILF, _("BUG: num_pattern_rules wrong! %u != %u"), fatal (NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
num_pattern_rules, rules); num_pattern_rules, rules);
} }
} }

View File

@ -1,3 +1,13 @@
2009-06-09 Paul Smith <psmith@gnu.org>
* scripts/features/parallelism: Add a test for re-exec with
jobserver master override. Savannah bug #18124.
2009-06-08 Paul Smith <psmith@gnu.org>
* scripts/features/targetvars: Add a test for continued target
vars after a semicolon. Savannah bug #17521.
2009-06-07 Paul Smith <psmith@gnu.org> 2009-06-07 Paul Smith <psmith@gnu.org>
* scripts/features/se_explicit: Make sure we catch defining * scripts/features/se_explicit: Make sure we catch defining

View File

@ -140,6 +140,29 @@ intermed: | phony ; touch $@
phony: ; : phony', '-rR -j', ': phony'); phony: ; : phony', '-rR -j', ': phony');
unlink('target'); unlink('target');
# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
# We can't test this directly because there's no way a makefile can
# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
# by looking for "disabling jobserver mode" warnings; we should only
# get one from the original invocation and none from the re-exec.
# See Savannah bug #18124
run_make_test(q!
-include inc.mk
recur:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@rm -f inc.mk
@$(MAKE) -j2 -f #MAKEFILE# all
all:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo $@
inc.mk:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo 'FOO = bar' > $@
!,
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
unlink('inc.mk');
# Make sure that all jobserver FDs are closed if we need to re-exec the # Make sure that all jobserver FDs are closed if we need to re-exec the
# master copy. # master copy.

View File

@ -237,6 +237,15 @@ a: ; @echo "$(FOO)"
run_make_test(undef, 'FOO=C', "C f1\n"); run_make_test(undef, 'FOO=C', "C f1\n");
# TEST #20: Check for continuation after semicolons
run_make_test(q!
a: A = 'hello; \
world'
a: ; @echo $(A)
!,
'', "hello; world\n");
# TEST #19: Test define/endef variables as target-specific vars # TEST #19: Test define/endef variables as target-specific vars
# run_make_test(' # run_make_test('

View File

@ -91,7 +91,7 @@ readdir (DIR *dir)
if (!((i = sys$search (dfab)) & 1)) if (!((i = sys$search (dfab)) & 1))
{ {
DB (DB_VERBOSE, (_("sys$search failed with %d\n"), i)); DB (DB_VERBOSE, (_("sys$search() failed with %d\n"), i));
return (NULL); return (NULL);
} }