From faedfdb0afd0f774bd58b5a30ca8117d70fa85c7 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sat, 28 Jan 2023 11:03:54 -0500 Subject: [SV 63667] In .POSIX, use shell flags -c when ignoring errors * src/variable.c (lookup_variable_for_file): New function to retrieve a variable assignment in a file context. * src/variable.h (lookup_variable_for_file): Declare it. * src/job.c (construct_command_argv): Look up .SHELLFLAGS. If .POSIX is set and we're using the default value, choose -c if we're ignoring errors else choose -ec. (construct_command_argv_internal): Ditto. * tests/scripts/targets/POSIX: Add tests. --- src/job.c | 13 +++++++++++-- src/variable.c | 23 +++++++++++++++++++++++ src/variable.h | 2 ++ 3 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src') 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); -- cgit v1.2.1