[SV 47151] Exit with 1 when checking recursive make -q

* job.h (struct child): New bit to mark recursive command lines.
* job.c (start_job_command): Set the recursive command line bit.
(reap_children): If the child is a recursive command and it exits
with 1 during question mode, don't print an error and exit with 1.
* tests/scripts/options/dash-q: Add a regression test.
This commit is contained in:
Paul Smith 2016-02-28 20:20:18 -05:00
parent bccd01354b
commit 89e18c12eb
3 changed files with 25 additions and 7 deletions

22
job.c
View File

@ -819,8 +819,6 @@ reap_children (int block, int err)
break;
}
child_failed = exit_sig != 0 || exit_code != 0;
/* Search for a child matching the deceased one. */
lastc = 0;
for (c = children; c != 0; lastc = c, c = c->next)
@ -832,6 +830,15 @@ reap_children (int block, int err)
Ignore it; it was inherited from our invoker. */
continue;
/* Determine the failure status: 0 for success, 1 for updating target in
question mode, 2 for anything else. */
if (exit_sig == 0 && exit_code == 0)
child_failed = MAKE_SUCCESS;
else if (exit_sig == 0 && exit_code == 1 && question_flag && c->recursive)
child_failed = MAKE_TROUBLE;
else
child_failed = MAKE_FAILURE;
DB (DB_JOBS, (child_failed
? _("Reaping losing child %p PID %s %s\n")
: _("Reaping winning child %p PID %s %s\n"),
@ -867,10 +874,10 @@ reap_children (int block, int err)
delete non-precious targets, and abort. */
static int delete_on_error = -1;
if (!dontcare)
if (!dontcare && child_failed == MAKE_FAILURE)
child_error (c, exit_code, exit_sig, coredump, 0);
c->file->update_status = us_failed;
c->file->update_status = child_failed == MAKE_FAILURE ? us_failed : us_question;
if (delete_on_error == -1)
{
struct file *f = lookup_file (".DELETE_ON_ERROR");
@ -982,7 +989,7 @@ reap_children (int block, int err)
if (!err && child_failed && !dontcare && !keep_going_flag &&
/* fatal_error_signal will die with the right signal. */
!handling_fatal_signal)
die (MAKE_FAILURE);
die (child_failed);
/* Only block for one child. */
block = 0;
@ -1188,14 +1195,15 @@ start_job_command (struct child *child)
++p;
}
child->recursive = ((flags & COMMANDS_RECURSE) != 0);
/* Update the file's command flags with any new ones we found. We only
keep the COMMANDS_RECURSE setting. Even this isn't 100% correct; we are
now marking more commands recursive than should be in the case of
multiline define/endef scripts where only one line is marked "+". In
order to really fix this, we'll have to keep a lines_flags for every
actual line, after expansion. */
child->file->cmds->lines_flags[child->command_line - 1]
|= flags & COMMANDS_RECURSE;
child->file->cmds->lines_flags[child->command_line - 1] |= flags & COMMANDS_RECURSE;
/* POSIX requires that a recipe prefix after a backslash-newline should
be ignored. Remove it now so the output is correct. */

1
job.h
View File

@ -109,6 +109,7 @@ struct child
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */
unsigned int dontcare:1; /* Saved dontcare flag. */
};

View File

@ -74,4 +74,13 @@ build-y: build-x
',
'-q build-y', "#MAKE#: *** No rule to make target 'build-stamp-2', needed by 'build-arch'. Stop.\n", 512);
# TEST 9 : Savannah bug # 47151
# Make sure we exit with 1 when invoking a recursive make
run_make_test('
foo: bar ; echo foo
bar: ; @$(MAKE) -f #MAKEFILE# baz
baz: ; echo baz
',
'-q foo', '', 256);
1;