diff --git a/src/job.c b/src/job.c index 7533553f..d145bef9 100644 --- a/src/job.c +++ b/src/job.c @@ -2886,7 +2886,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, return 0; if (shellflags == 0) - shellflags = posix_pedantic ? "-ec" : "-c"; + shellflags = posix_pedantic && NONE_SET (flags, COMMANDS_NOERROR) ? "-ec" : "-c"; /* See if it is safe to parse commands internally. */ if (shell == 0) @@ -3710,6 +3710,7 @@ construct_command_argv (char *line, char **restp, struct file *file, char **argv; { + struct variable *var; /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; @@ -3770,7 +3771,15 @@ construct_command_argv (char *line, char **restp, struct file *file, } #endif /* __EMX__ */ - shellflags = allocated_variable_expand_for_file ("$(.SHELLFLAGS)", file); + var = lookup_variable_for_file (STRING_SIZE_TUPLE (".SHELLFLAGS"), file); + if (!var) + shellflags = xstrdup (""); + else if (posix_pedantic && var->origin == o_default) + /* In POSIX mode we default to -ec, unless we're ignoring errors. */ + shellflags = xstrdup (ANY_SET (cmd_flags, COMMANDS_NOERROR) ? "-c" : "-ec"); + else + shellflags = allocated_variable_expand_for_file (var->value, file); + ifs = allocated_variable_expand_for_file ("$(IFS)", file); warn_undefined_variables_flag = save; diff --git a/src/variable.c b/src/variable.c index 259093f8..ec87ce9b 100644 --- a/src/variable.c +++ b/src/variable.c @@ -538,6 +538,29 @@ lookup_variable (const char *name, size_t length) return 0; } +/* Lookup a variable whose name is a string starting at NAME + and with LENGTH chars. NAME need not be null-terminated. + Returns address of the 'struct variable' containing all info + on the variable, or nil if no such variable is defined. */ + +struct variable * +lookup_variable_for_file (const char *name, size_t length, struct file *file) +{ + struct variable *var; + struct variable_set_list *savev; + + if (file == NULL) + return lookup_variable (name, length); + + savev = current_variable_set_list; + current_variable_set_list = file->variables; + + var = lookup_variable (name, length); + + current_variable_set_list = savev; + + return var; +} /* Lookup a variable whose name is a string starting at NAME and with LENGTH chars in set SET. NAME need not be null-terminated. diff --git a/src/variable.h b/src/variable.h index c7bbe8f5..244da4f8 100644 --- a/src/variable.h +++ b/src/variable.h @@ -182,6 +182,8 @@ void define_new_function(const floc *flocp, const char *name, unsigned int min, unsigned int max, unsigned int flags, gmk_func_ptr func); struct variable *lookup_variable (const char *name, size_t length); +struct variable *lookup_variable_for_file (const char *name, size_t length, + struct file *file); struct variable *lookup_variable_in_set (const char *name, size_t length, const struct variable_set *set); diff --git a/tests/scripts/targets/POSIX b/tests/scripts/targets/POSIX index ade0b1ee..325d58cb 100644 --- a/tests/scripts/targets/POSIX +++ b/tests/scripts/targets/POSIX @@ -7,12 +7,52 @@ $details = ""; # Ensure turning on .POSIX enables the -e flag for the shell -run_make_test(qq! +run_make_test(q! .POSIX: -all: ; \@#HELPER# -q fail 1; true +all: ; @#HELPER# -q fail 1; #HELPER# out hello !, '', "#MAKE#: *** [#MAKEFILE#:3: all] Error 1\n", 512); +# But explicit settings must still take precedence + +run_make_test(q! +.POSIX: +all: ; @-#HELPER# -q fail 1; #HELPER# out hello +.SHELLFLAGS = -c +!, + '', "hello"); + +run_make_test(q! +.POSIX: +all: ; @-#HELPER# -q fail 1; #HELPER# out hello +all: .SHELLFLAGS = -c +!, + '', "hello"); + +# SV 63667: We shouldn't add -e to sh if errors are ignored + +run_make_test(q! +.POSIX: +all: ; @-#HELPER# -q fail 1; #HELPER# out hello +!, + '', "hello\n"); + +# But explicit settings must still take precedence + +run_make_test(q! +.POSIX: +all: ; @-#HELPER# -q fail 1; #HELPER# out hello +.SHELLFLAGS = -ec +!, + '', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)\n"); + +run_make_test(q! +.POSIX: +all: ; @-#HELPER# -q fail 1; #HELPER# out hello +all: .SHELLFLAGS = -ec +!, + '', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)\n"); + # User settings must override .POSIX # In the standard .POSIX must be the first thing in the makefile # but we relax that rule in GNU Make.