[SV 64085] Handle .POSIX plus .IGNORE correctly

POSIX requires that a conforming makefile should not use -e if
 1) make is invoked with -i
 2) A .IGNORE target exists with no prerequisites
 3) The current target is a prerequisite of .IGNORE

* src/job.c (start_job_command): Add the target's flags when
constructing argv so it can check (3) above.
(construct_command_argv_internal): Don't set shellflags if it's not
set: this only happens if we're parsing for the slow path and we
don't need them.
(construct_command_argv): Don't allocate buffers if not needed.
When detecting "-ec", check the global ignore_errors_flag and the
current command line flags.
* tests/scripts/targets/IGNORE: Add tests for .IGNORE.
* tests/scripts/targets/POSIX: Add tests for the three cases above.
This commit is contained in:
Paul Smith 2024-02-04 19:41:50 -05:00
parent 07187db947
commit 3176b60566
3 changed files with 61 additions and 10 deletions

View file

@ -1257,7 +1257,7 @@ start_job_command (struct child *child)
}
#else
argv = construct_command_argv (p, &end, child->file,
child->file->cmds->lines_flags[child->command_line - 1],
child->file->cmds->lines_flags[child->command_line - 1] | child->file->command_flags,
&child->sh_batch_file);
#endif
if (end == NULL)
@ -2836,9 +2836,6 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
if (*line == '\0')
return 0;
if (shellflags == 0)
shellflags = posix_pedantic && NONE_SET (flags, COMMANDS_NOERROR) ? "-ec" : "-c";
/* See if it is safe to parse commands internally. */
if (shell == 0)
shell = default_shell;
@ -3628,7 +3625,9 @@ char **
construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char **batch_filename)
{
char *shell, *ifs, *shellflags;
char *shell, *ifs;
char *allocflags = NULL;
const char *shellflags;
char **argv;
{
@ -3695,12 +3694,14 @@ construct_command_argv (char *line, char **restp, struct file *file,
var = lookup_variable_for_file (STRING_SIZE_TUPLE (".SHELLFLAGS"), file);
if (!var)
shellflags = xstrdup ("");
else if (posix_pedantic && var->origin == o_default)
shellflags = "";
else if (var->origin != o_default)
shellflags = allocflags = allocated_expand_string_for_file (var->value, file);
else if (posix_pedantic && !ignore_errors_flag && NONE_SET (cmd_flags, COMMANDS_NOERROR))
/* In POSIX mode we default to -ec, unless we're ignoring errors. */
shellflags = xstrdup (ANY_SET (cmd_flags, COMMANDS_NOERROR) ? "-c" : "-ec");
shellflags = "-ec";
else
shellflags = allocated_expand_string_for_file (var->value, file);
shellflags = "-c";
ifs = allocated_expand_variable_for_file (STRING_SIZE_TUPLE ("IFS"), file);
@ -3711,7 +3712,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
cmd_flags, batch_filename);
free (shell);
free (shellflags);
free (allocflags);
free (ifs);
return argv;

View file

@ -0,0 +1,28 @@
# -*-perl-*-
$description = "Test the behaviour of the .IGNORE target.";
$details = "";
# Without any ignore
run_make_test(q!
all: ; @#HELPER# -q fail 1
!,
'', "#MAKE#: *** [#MAKEFILE#:2: all] Error 1", 512);
# Global .IGNORE
run_make_test(q!
.IGNORE:
all: ; @#HELPER# -q fail 1
!,
'', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)");
# Specific .IGNORE
run_make_test(q!
.IGNORE: all
all: ; @#HELPER# -q fail 1
!,
'', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)");
1;

View file

@ -37,6 +37,28 @@ all: ; @-#HELPER# -q fail 1; #HELPER# out hello
!,
'', "hello\n");
# SV 64085: Also don't add -e if -i or .IGNORE is used
run_make_test(q!
.POSIX:
all: ; @#HELPER# -q fail 1; #HELPER# out hello
!,
'-i', "hello\n");
run_make_test(q!
.POSIX:
.IGNORE:
all: ; @#HELPER# -q fail 1; #HELPER# out hello
!,
'', "hello\n");
run_make_test(q!
.POSIX:
.IGNORE: all
all: ; @#HELPER# -q fail 1; #HELPER# out hello
!,
'', "hello\n");
# But explicit settings must still take precedence
run_make_test(q!