On Thu, Dec 29, 2016 at 9:39 PM, Eduardo Bustamante <dual...@gmail.com> wrote: > I'm adding the bug-bash list, since I think this is actually a bug in > the parse_comsub function, or maybe in execute_command_internal. I > haven't been able to figure it out yet. What I do know is that these > two should behave the same: I'm not sure what was I thinking, but these are of course very different things (comsub and subshell) :-)
I still think this is a bug, because line number information (line_number, line_number_for_err_trap and the line attribute in the different command structures) is handled inconsistently. The problem is that line information is lost when executing the body of a function, so what bash does is to store line number information in the command structures, so that it's able to correctly report to the ERR trap when it is triggered. But for some reason this is not handled in a consistent manner for different types of commands, so the following fail: - subshells e.g. (exit 17) - arithmetic commands e.g. (( 0 )) - conditional commands, e.g. [[ a = b ]] I don't think this applies for the following types: if, case, for, arith-for, but I may be wrong. The attached err_lineno patch is a proposed fix. The reported line number will be the closing line in the case of a subshell and the other multi-line constructs. This seems to match the current behavior when executing outside a function.
diff --git a/command.h b/command.h index 3bf479a..678df79 100644 --- a/command.h +++ b/command.h @@ -353,6 +353,7 @@ typedef struct group_com { typedef struct subshell_com { int flags; + int line; COMMAND *command; } SUBSHELL_COM; diff --git a/copy_cmd.c b/copy_cmd.c index 826e0c3..ec71b70 100644 --- a/copy_cmd.c +++ b/copy_cmd.c @@ -221,6 +221,7 @@ copy_subshell_command (com) new_subshell = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM)); new_subshell->command = copy_command (com->command); new_subshell->flags = com->flags; + new_subshell->line= com->line; return (new_subshell); } diff --git a/execute_cmd.c b/execute_cmd.c index 2fff093..29c3e2f 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -606,7 +606,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, /* Fork a subshell, turn off the subshell bit, turn off job control and call execute_command () on the command again. */ - line_number_for_err_trap = line_number; /* XXX - save value? */ + line_number_for_err_trap = line_number = command->value.Subshell->line; tcmd = make_command_string (command); paren_pid = make_child (p = savestring (tcmd), asynchronous); @@ -3600,7 +3600,7 @@ execute_arith_command (arith_command) save_line_number = line_number; this_command_name = "(("; /* )) */ - line_number = arith_command->line; + line_number_for_err_trap = line_number = arith_command->line; /* If we're in a function, update the line number information. */ if (variable_context && interactive_shell) { @@ -3801,7 +3801,7 @@ execute_cond_command (cond_command) save_line_number = line_number; this_command_name = "[["; - line_number = cond_command->line; + line_number_for_err_trap = line_number = cond_command->line; /* If we're in a function, update the line number information. */ if (variable_context && interactive_shell) { diff --git a/make_cmd.c b/make_cmd.c index b42e9ff..6067ecb 100644 --- a/make_cmd.c +++ b/make_cmd.c @@ -822,6 +822,7 @@ make_subshell_command (command) temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM)); temp->command = command; temp->flags = CMD_WANT_SUBSHELL; + temp->line = line_number; return (make_command (cm_subshell, (SIMPLE_COM *)temp)); }