From 31f4d468b60eb27d768ef56d0a8b4982346465d9 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 7 Nov 2022 10:25:28 -0500 Subject: [PATCH] fix for displaying `local -'; fix for trap and POSIX interp 1602; fix for readline redisplay when the last invisible character in the prompt string is not on the last line --- CWRU/CWRU.chlog | 46 +++++++++++++++++++++++++++ builtins/caller.def | 7 ++++- builtins/common.c | 17 +++++----- builtins/setattr.def | 14 ++++++--- execute_cmd.c | 4 +-- jobs.c | 2 +- lib/readline/display.c | 70 +++++++++++++++++++++++++++++++++++------ lib/sh/tmpfile.c | 24 ++++++++++++-- po/hr.gmo | Bin 178369 -> 178345 bytes po/hr.po | 66 +++++++++++++++++++------------------- subst.c | 10 ++++++ tests/trap6.sub | 11 +++++++ trap.c | 18 +++++++++-- trap.h | 1 + 14 files changed, 226 insertions(+), 64 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 824325bc..d5f4ad42 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -4291,3 +4291,49 @@ lib/readline/isearch.c lib/readline/misc.c - rl_digit_argument: call _rl_del_executing_keyseq after rl_execute_next + + 11/3 + ---- +builtins/setattr.def + - show_localname_attributes: special-case "-" local variable, since + there is no `declare -' equivalent. + Reported by Emanuele Torre . + + 11/4 + ---- +lib/sh/tmpfile.c + - sh_mktmpname,sh_mktmpfd: use get_urandom32() instead of random() if + we're not using mktemp or mkstemp and the system provides the + appropriate support + +trap.c + - trap_variable_context: new variable, set to variable_context every + time a trap string runs (that is, every time running_trap is set to + a value > 0) in _run_trap_internal, run_exit_trap, run_pending_traps + +trap.h + - trap_variable_context: extern declaration + +builtins/common.c + - get_exitstat: if the `return' builtin is running, we are running a + trap (but not the DEBUG trap), and the return would cause the trap + string to complete (variable_context == trap_variable_context, so + we haven't executed another shell function), use the last command + exit value as the return status. POSIX interp 1602, from + https://www.austingroupbugs.net/view.php?id=1602 + + 11/4 + ---- + +lib/readline/display.c + - local_prompt_invis_chars: new array variable, similar to + local_prompt_newlines, that keeps track of the number of invisible + characters on each line of the prompt string. Use in WRAP_OFFSET + macro with eye to using in W_OFFSET as well. Used for the case where + the last line of the prompt is not the last line with invisible + characters. Can use this in more calculations replacing wrap_offset + and prompt_invis_chars_first_line going forward. Inspired by report + from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1018851 + - update_line: use local_prompt_invis_chars to set _rl_last_c_pos + correctly when on a non-terminal prompt line that contains + invisible characters diff --git a/builtins/caller.def b/builtins/caller.def index 1000979d..57746a29 100644 --- a/builtins/caller.def +++ b/builtins/caller.def @@ -140,7 +140,12 @@ N_("Returns the context of the current subroutine call.\n\ provide a stack trace.\n\ \n\ The value of EXPR indicates how many call frames to go back before the\n\ - current one; the top frame is frame 0."), + current one; the top frame is frame 0.\n\ + \n\ + Exit Status:\n\ + Returns 0 unless the shell is not executing a shell function or EXPR\n\ + is invalid." +), (char *)NULL }; diff --git a/builtins/common.c b/builtins/common.c index 19b00c4d..b9705c02 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -564,13 +564,16 @@ get_exitstat (list) if (list == 0) { - /* If we're not running the DEBUG trap, the return builtin, when not - given any arguments, uses the value of $? before the trap ran. If - given an argument, return uses it. This means that the trap can't - change $?. The DEBUG trap gets to change $?, though, since that is - part of its reason for existing, and because the extended debug mode - does things with the return value. */ - if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1) + /* If we're not running the DEBUG trap, and haven't executed a shell + function from the trap action, the return builtin, when not given + any arguments, uses the value of $? before the trap ran. The business + about executing a shell function from the trap action is from POSIX + interp 1602 (10/2022). If given an argument, return uses it + unconditionally. This means that the trap can't change $?. The DEBUG + trap gets to change $?, though, since that is part of its reason for + existing, and because the extended debug mode does things with the + return value. */ + if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1 && variable_context == trap_variable_context) return (trap_saved_exit_value); return (last_command_exit_value); } diff --git a/builtins/setattr.def b/builtins/setattr.def index 50c8edf6..43d43138 100644 --- a/builtins/setattr.def +++ b/builtins/setattr.def @@ -38,16 +38,16 @@ $PRODUCES setattr.c #include "../flags.h" #include "common.h" #include "bashgetopt.h" +#include "builtext.h" extern sh_builtin_func_t *this_shell_builtin; -#ifdef ARRAY_VARS -extern int declare_builtin PARAMS((WORD_LIST *)); -#endif - #define READONLY_OR_EXPORT \ (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin) +#define SPECIAL_LOCAL(n) \ + (this_shell_builtin == local_builtin && n[0] == '-' && n[1] == 0) + $BUILTIN export $FUNCTION export_builtin $SHORT_DOC export [-fn] [name[=value] ...] or export -p @@ -561,7 +561,11 @@ show_localname_attributes (name, nodefs) if (var && local_p (var) && var->context == variable_context) /* show every variable with attributes, even unset ones */ { - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + /* There is no equivalent `declare -'. */ + if (STREQ (var->name, "-")) + printf ("local -\n"); + else + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); return (0); } else diff --git a/execute_cmd.c b/execute_cmd.c index a7f42175..b99c972b 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -1676,8 +1676,8 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) dispose_redirects (command->redirects); command->redirects = (REDIRECT *)NULL; #if 0 - /* TAG: bash-5.3 kre 10/24/2022 */ #if defined (PROCESS_SUBSTITUTION) && defined (JOB_CONTROL) + /* TAG: bash-5.3 kre 10/24/2022 */ if (user_subshell && command->type == cm_subshell) { procsub_clear (); @@ -1685,7 +1685,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) } #endif #endif - } + } if (command->type == cm_subshell) tcom = command->value.Subshell->command; diff --git a/jobs.c b/jobs.c index 859a0ff5..03a96053 100644 --- a/jobs.c +++ b/jobs.c @@ -2712,7 +2712,7 @@ wait_for_background_pids (ps) procsub_waitpid (last_procsub_child->pid); reap_procsubs (); /* closes fd */ #endif - + /* POSIX.2 says the shell can discard the statuses of all completed jobs if `wait' is called with no arguments. */ mark_dead_jobs_as_notified (1); diff --git a/lib/readline/display.c b/lib/readline/display.c index df9d7492..f7ffd465 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -282,6 +282,10 @@ static int prompt_physical_chars; characters in the prompt or use heuristics about where they are. */ static int *local_prompt_newlines; +/* An array saying how many invisible characters are in each line of the + prompt. */ +static int *local_prompt_invis_chars; + /* set to a non-zero value by rl_redisplay if we are marking modified history lines and the current line is so marked. */ static int modmark; @@ -295,6 +299,7 @@ static int line_totbytes; static char *saved_local_prompt; static char *saved_local_prefix; static int *saved_local_prompt_newlines; +static int *saved_local_prompt_invis_chars; static int saved_last_invisible; static int saved_visible_length; @@ -356,7 +361,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) { char *r, *ret, *p, *igstart, *nprompt, *ms; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; - int mlen, newlines, newlines_guess, bound, can_add_invis; + int mlen, newlines, newlines_guess, bound, can_add_invis, lastinvis; int mb_cur_max; /* We only expand the mode string for the last line of a multiline prompt @@ -399,7 +404,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) *vlp = l; local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2); - local_prompt_newlines[0] = 0; + local_prompt_invis_chars = (int *) xrealloc (local_prompt_invis_chars, sizeof (int) * 2); + local_prompt_newlines[0] = local_prompt_invis_chars[0] = 0; local_prompt_newlines[1] = -1; return r; @@ -414,15 +420,20 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l, _rl_screenwidth) : APPROX_DIV(l, 80); local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1)); local_prompt_newlines[newlines = 0] = 0; + local_prompt_invis_chars = (int *) xrealloc (local_prompt_invis_chars, sizeof (int) * (newlines_guess + 1)); + local_prompt_invis_chars[0] = 0; for (rl = 1; rl <= newlines_guess; rl++) - local_prompt_newlines[rl] = -1; + { + local_prompt_newlines[rl] = -1; + local_prompt_invis_chars[rl] = 0; + } rl = physchars = 0; /* mode string now part of nprompt */ invfl = 0; /* invisible chars in first line of prompt */ invflset = 0; /* we only want to set invfl once */ igstart = 0; /* we're not ignoring any characters yet */ - for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++) + for (ignoring = last = ninvis = lastinvis = 0, p = nprompt; p && *p; p++) { /* This code strips the invisible character string markers RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ @@ -447,6 +458,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) counter. */ if (invflset && newlines == 1) invfl = ninvis; + local_prompt_invis_chars[newlines - 1] = ninvis - lastinvis; + lastinvis = ninvis; } if (p != (igstart + 1)) last = r - ret - 1; @@ -511,6 +524,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) else new = r - ret; local_prompt_newlines[++newlines] = new; + local_prompt_invis_chars[newlines - 1] = ninvis - lastinvis; + lastinvis = ninvis; } /* What if a physical character of width >= 2 is split? There is @@ -525,6 +540,9 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) if (rl <= _rl_screenwidth) invfl = ninvis; + /* Make sure we account for invisible characters on the last line. */ + local_prompt_invis_chars[newlines] = ninvis - lastinvis; + *r = '\0'; if (lp) *lp = rl; @@ -964,6 +982,9 @@ rl_redisplay (void) in the first physical line of the prompt. wrap_offset - prompt_invis_chars_first_line is usually the number of invis chars on the second (or, more generally, last) line. */ + /* XXX - There is code that assumes that all the invisible characters occur + on the first and last prompt lines; change that to use + local_prompt_invis_chars */ /* This is zero-based, used to set the newlines */ prompt_lines_estimate = lpos / _rl_screenwidth; @@ -982,6 +1003,7 @@ rl_redisplay (void) } /* Now set lpos from the last newline */ + /* XXX - change to use local_prompt_invis_chars[] */ if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line); else @@ -1249,10 +1271,9 @@ rl_redisplay (void) second and subsequent lines start at inv_lbreaks[N], offset by OFFSET (which has already been calculated above). */ -#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset) -#define WRAP_OFFSET(line, offset) ((line == 0) \ - ? (offset ? INVIS_FIRST() : 0) \ - : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0)) +#define INVIS_FIRST() (local_prompt_invis_chars[0]) +#define WRAP_OFFSET(line, offset) ((line <= prompt_last_screen_line) ? local_prompt_invis_chars[line] : 0) + #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) #define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) @@ -1263,6 +1284,9 @@ rl_redisplay (void) #define INV_LINE(line) (invisible_line + inv_lbreaks[line]) #define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line]) +#define INV_CHARS_CURRENT_PROMPT_LINE(line) \ + (local_prompt_invis_chars[line] > 0) + #define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ _rl_last_c_pos != o_cpos && \ _rl_last_c_pos > wrap_offset && \ @@ -1319,6 +1343,7 @@ rl_redisplay (void) between the first and last lines of the prompt, if the prompt consumes more than two lines. It's usually right */ /* XXX - not sure this is ever executed */ + /* XXX - use local_prompt_invis_chars[linenum] */ _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); /* If this is the line with the prompt, we might need to @@ -1413,6 +1438,7 @@ rl_redisplay (void) only need to reprint it if the cursor is before the last invisible character in the prompt string. */ /* XXX - why not use local_prompt_len? */ + /* XXX - This is right only if the prompt is a single line. */ nleft = prompt_visible_length + wrap_offset; if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) @@ -1895,6 +1921,8 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l /* See comments at dumb_update: for an explanation of this heuristic */ if (nmax < omax) goto clear_rest_of_line; + /* XXX - need to use WRAP_OFFSET(current_line, wrap_offset) instead of + W_OFFSET - XXX */ else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) goto clear_rest_of_line; else @@ -2076,7 +2104,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l } /* count of invisible characters in the current invisible line. */ - current_invis_chars = W_OFFSET (current_line, wrap_offset); + current_invis_chars = WRAP_OFFSET (current_line, wrap_offset); if (_rl_last_v_pos != current_line) { _rl_move_vert (current_line); @@ -2140,6 +2168,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l else /* We take wrap_offset into account here so we can pass correct information to _rl_move_cursor_relative. */ + /* XXX - can use local_prompt_invis_chars[0] instead of wrap_offset */ _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark; cpos_adjusted = 1; } @@ -2183,6 +2212,7 @@ dumb_update: wrap_offset-prompt_invis_chars_first_line on the assumption that this is the number of invisible characters in the last line of the prompt. */ + /* XXX - CHANGE THIS USING local_prompt_invis_chars[current_line] */ if (wrap_offset > prompt_invis_chars_first_line && current_line == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth && @@ -2201,6 +2231,20 @@ dumb_update: wrap_offset >= prompt_invis_chars_first_line && _rl_horizontal_scroll_mode == 0) ADJUST_CPOS (prompt_invis_chars_first_line); + /* XXX - This is experimental. It's a start at supporting + prompts where a non-terminal line contains the last + invisible characters. We assume that we can use the + local_prompt_invis_chars array and that the current line + is completely filled with characters to _rl_screenwidth, + so we can either adjust by the number of bytes in the + current line or just go straight to _rl_screenwidth */ + else if (current_line > 0 && current_line < prompt_last_screen_line && + INV_CHARS_CURRENT_PROMPT_LINE(current_line) && + _rl_horizontal_scroll_mode == 0) + { + _rl_last_c_pos = _rl_screenwidth; + cpos_adjusted = 1; + } } else _rl_last_c_pos += temp; @@ -2212,6 +2256,8 @@ dumb_update: know for sure, so we use another heuristic calclulation below. */ if (nmax < omax) goto clear_rest_of_line; /* XXX */ + /* XXX - use WRAP_OFFSET(current_line, wrap_offset) here instead of + W_OFFSET since current_line == 0 */ else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) goto clear_rest_of_line; else @@ -3099,10 +3145,12 @@ rl_save_prompt (void) saved_invis_chars_first_line = prompt_invis_chars_first_line; saved_physical_chars = prompt_physical_chars; saved_local_prompt_newlines = local_prompt_newlines; + saved_local_prompt_invis_chars = local_prompt_invis_chars; local_prompt = local_prompt_prefix = (char *)0; local_prompt_len = 0; local_prompt_newlines = (int *)0; + local_prompt_invis_chars = (int *)0; prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; prompt_invis_chars_first_line = prompt_physical_chars = 0; @@ -3114,11 +3162,13 @@ rl_restore_prompt (void) FREE (local_prompt); FREE (local_prompt_prefix); FREE (local_prompt_newlines); + FREE (local_prompt_invis_chars); local_prompt = saved_local_prompt; local_prompt_prefix = saved_local_prefix; local_prompt_len = saved_local_length; local_prompt_newlines = saved_local_prompt_newlines; + local_prompt_invis_chars = saved_local_prompt_invis_chars; prompt_prefix_length = saved_prefix_length; prompt_last_invisible = saved_last_invisible; @@ -3131,7 +3181,7 @@ rl_restore_prompt (void) saved_local_length = 0; saved_last_invisible = saved_visible_length = saved_prefix_length = 0; saved_invis_chars_first_line = saved_physical_chars = 0; - saved_local_prompt_newlines = 0; + saved_local_prompt_newlines = saved_local_prompt_invis_chars = 0; } char * diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c index ef8b067b..d107e745 100644 --- a/lib/sh/tmpfile.c +++ b/lib/sh/tmpfile.c @@ -42,6 +42,10 @@ extern int errno; #endif +#if defined (HAVE_GETRANDOM) || defined (HAVE_ARC4RANDOM) || defined (HAVE_GETENTROPY) +# define USE_URANDOM32 +#endif + #define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL | O_BINARY) #define DEFAULT_TMPDIR "." /* bogus default, should be changed */ @@ -163,13 +167,21 @@ sh_mktmpname (nameroot, flags) filename = NULL; } #else /* !USE_MKTEMP */ +#ifndef USE_URANDOM32 sh_seedrand (); +#endif while (1) { + unsigned long x; +#ifdef USE_URANDOM32 + x = (unsigned long) ((flags & MT_USERANDOM) ? get_urandom32 () : ntmpfiles++); +#else + x = (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); +#endif filenum = (filenum << 1) ^ (unsigned long) time ((time_t *)0) ^ (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); + x; sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); if (tmpnamelen > 0 && tmpnamelen < 32) filename[tdlen + 1 + tmpnamelen] = '\0'; @@ -221,13 +233,21 @@ sh_mktmpfd (nameroot, flags, namep) *namep = filename; return fd; #else /* !USE_MKSTEMP */ +#ifndef USE_URANDOM32 sh_seedrand (); +#endif do { + unsigned long x; +#ifdef USE_URANDOM32 + x = (unsigned long) ((flags & MT_USERANDOM) ? get_urandom32 () : ntmpfiles++); +#else + x = (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); +#endif filenum = (filenum << 1) ^ (unsigned long) time ((time_t *)0) ^ (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); + x; sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); if (tmpnamelen > 0 && tmpnamelen < 32) filename[tdlen + 1 + tmpnamelen] = '\0'; diff --git a/po/hr.gmo b/po/hr.gmo index 228b369eecd208f14b7da572944d2bd3c66110c3..2ac09d9668627399041b601ef76378d982538276 100644 GIT binary patch delta 5292 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“)\n" " PWD puni naziv staze trenutnog radnog direktorija\n" " SHELLOPTS popis svih omogućenih opcija ljuske\n" -" TERM naziv vrste trenutnog terminala\n" +" TERM naziv tipa trenutnog terminala\n" " TIMEFORMAT pravilo za format ispisa „time“ statistika\n" " auto_resume ako nije prazan, učini da se naredbena riječ na naredbenom\n" " retku prvo potraži na popisu zaustavljenih poslova,\n" diff --git a/subst.c b/subst.c index c4fb7732..a72711e7 100644 --- a/subst.c +++ b/subst.c @@ -3058,7 +3058,12 @@ string_list_pos_params (pchar, list, quoted, pflags) { tlist = quote_list (list); word_list_remove_quoted_nulls (tlist); +#if 0 ret = string_list (tlist); +#else + /* TAG:bash-5.3 Aloxaf Yin 9/1/2022 */ + ret = string_list_dollar_star (tlist, 0, 0); +#endif } else if (pchar == '*' && quoted == 0 && ifs_is_null) /* XXX */ ret = expand_no_split_dollar_star ? string_list_dollar_star (list, quoted, 0) : string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ @@ -10367,7 +10372,12 @@ param_expand (string, sindex, quoted, expanded_something, quote the whole string, including the separators. If IFS is unset, the parameters are separated by ' '; if $IFS is null, the parameters are concatenated. */ +#if 0 temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list, quoted, 0) : string_list (list); +#else + /* TAG:bash-5.3 Aloxaf Yin 9/1/2022 */ + temp = string_list_dollar_star (list, quoted, 0); +#endif if (temp) { temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp) : temp; diff --git a/tests/trap6.sub b/tests/trap6.sub index 72685580..9dbb0d6d 100644 --- a/tests/trap6.sub +++ b/tests/trap6.sub @@ -26,3 +26,14 @@ fn echo after 2 unset -f fn + +# since this sets the exit trap, it has to go last + +set +o functrace +# posix interp 1602 +ReturnFalse() +{ + false ; return +} + +trap 'ReturnFalse && echo "woops"' EXIT diff --git a/trap.c b/trap.c index dd0245e6..9cedf7eb 100644 --- a/trap.c +++ b/trap.c @@ -113,6 +113,10 @@ int pending_traps[NSIG]; trap command (e.g., when `return' is executed in the trap command). */ int running_trap; +/* The variable context (function execution level) when we began running + this trap command. */ +int trap_variable_context; + /* Set to last_command_exit_value before running a trap. */ int trap_saved_exit_value; @@ -298,7 +302,7 @@ run_pending_traps () { register int sig; int x; - volatile int old_exit_value, old_running; + volatile int old_exit_value, old_running, old_context; WORD_LIST *save_subst_varlist; HASH_TABLE *save_tempenv; sh_parser_state_t pstate; @@ -336,6 +340,7 @@ run_pending_traps () ps = save_pipestatus_array (); #endif old_running = running_trap; + old_context = trap_variable_context; for (sig = 1; sig < NSIG; sig++) { @@ -345,6 +350,7 @@ run_pending_traps () { /* XXX - set last_command_exit_value = trap_saved_exit_value here? */ running_trap = sig + 1; + trap_variable_context = variable_context; if (sig == SIGINT) { @@ -465,6 +471,7 @@ run_pending_traps () if (function_code) { running_trap = old_running; /* XXX */ + trap_variable_context = old_context; /* caller will set last_command_exit_value */ sh_longjmp (return_catch, 1); } @@ -473,6 +480,7 @@ run_pending_traps () pending_traps[sig] = 0; /* XXX - move before evalstring? */ running_trap = old_running; + trap_variable_context = old_context; } } @@ -992,6 +1000,7 @@ run_exit_trap () retval = trap_saved_exit_value; running_trap = 1; + trap_variable_context = variable_context; code = setjmp_nosigs (top_level); @@ -1047,7 +1056,7 @@ _run_trap_internal (sig, tag) char *trap_command, *old_trap; int trap_exit_value; volatile int save_return_catch_flag, function_code; - int old_modes, old_running, old_int; + int old_modes, old_running, old_int, old_context; int flags; procenv_t save_return_catch; WORD_LIST *save_subst_varlist; @@ -1057,7 +1066,7 @@ _run_trap_internal (sig, tag) ARRAY *ps; #endif - old_modes = old_running = -1; + old_modes = old_running = old_context = -1; trap_exit_value = function_code = 0; trap_saved_exit_value = last_command_exit_value; @@ -1076,12 +1085,14 @@ _run_trap_internal (sig, tag) old_trap = trap_list[sig]; old_modes = sigmodes[sig]; old_running = running_trap; + old_context = trap_variable_context; sigmodes[sig] |= SIG_INPROGRESS; sigmodes[sig] &= ~SIG_CHANGED; /* just to be sure */ trap_command = savestring (old_trap); running_trap = sig + 1; + trap_variable_context = variable_context; old_int = interrupt_state; /* temporarily suppress pending interrupts */ CLRINTERRUPT; @@ -1141,6 +1152,7 @@ _run_trap_internal (sig, tag) running_trap = old_running; interrupt_state = old_int; + trap_variable_context = old_context; if (sigmodes[sig] & SIG_CHANGED) { diff --git a/trap.h b/trap.h index 89402a1b..518113c9 100644 --- a/trap.h +++ b/trap.h @@ -63,6 +63,7 @@ extern char *trap_list[]; extern int trapped_signal_received; extern int wait_signal_received; extern int running_trap; +extern int trap_variable_context; extern int trap_saved_exit_value; extern int suppress_debug_trap_verbose;