diff options
author | Chet Ramey <chet.ramey@case.edu> | 2014-05-13 16:19:42 -0400 |
---|---|---|
committer | Chet Ramey <chet.ramey@case.edu> | 2014-05-13 16:19:42 -0400 |
commit | fe570ea12aca33c896a88ef23275cc3bd3eaf75e (patch) | |
tree | 9ad6616939abc112680d97dcc63be666c7f42d43 | |
parent | 098cbb5c3d196ffc19434b1977a9a3e08bd2a540 (diff) | |
download | bash-fe570ea12aca33c896a88ef23275cc3bd3eaf75e.tar.gz |
commit bash-20140509 snapshot
-rw-r--r-- | CWRU/CWRU.chlog | 40 | ||||
-rw-r--r-- | arrayfunc.c | 4 | ||||
-rw-r--r-- | bashline.c | 6 | ||||
-rw-r--r-- | builtins/read.def | 7 | ||||
-rw-r--r-- | lib/glob/gmisc.c | 2 | ||||
-rw-r--r-- | lib/readline/input.c | 8 | ||||
-rw-r--r-- | tests/shopt.right | 6 | ||||
-rw-r--r-- | trap.c | 1 | ||||
-rw-r--r-- | variables.c | 119 | ||||
-rw-r--r-- | variables.h | 2 |
10 files changed, 153 insertions, 42 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 09397231..af12138b 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6230,3 +6230,43 @@ lib/glob/glob.c extglob is enabled, use glob_dirscan to find the real last occurrence of `/' to avoid being confused by slashes in extglob patterns. Fix for bug reported by Pierre Gaston <pierre.gaston@gmail.com> + + 5/6 + --- +variables.c + - make_local_variable: only set the att_invisible attribute if + no_invisible_vars isn't set + - find_variable_for_assignment: new function, intended to be called by + code that eventually wants to assign a value to the variable; will not + skip invisible variables; currently identical to find_variable + - find_variable_no_invisible: new function, finds the first visible + instance of variable with a given name in the variable context chain; + eventually will be used to replace find_variable; separate right now + for testing + +variables.h + - find_variable_for_assignment: extern declaration + - find_variable_no_invisible: extern declaration + + 5/7 + --- +variables.c + - make_local_variable: don't clear `invisible' attribute if we are + returning an existing local variable at the right context. Let the + upper layers do that. Fixes bug reported by Dan Douglas + <ormaaj@gmail.com> + + 5/8 + --- +lib/readline/input.c + - rl_getc: call RL_CHECK_SIGNALS if a read(2) is interrupted (-1/EINTR) + by SIGALRM or SIGVTALRM (placeholder for non-keyboard-generated + signals of interest) + +builtins/read.def + - edit_line: call bashline_set_event_hook and + bashline_reset_event_hook around call to readline(), so the right + signal handling happens + - read_builtin: make sure we add an unwind_protect call to + bashline_reset_event_hook. These changes fix bug reported in + https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1317476 diff --git a/arrayfunc.c b/arrayfunc.c index a89e67f1..91317142 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -934,11 +934,7 @@ array_variable_part (s, subp, lenp) var = find_variable (t); free (t); -#if 0 - return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var; -#else return var; /* now return invisible variables; caller must handle */ -#endif } #define INDEX_ERROR() \ @@ -202,6 +202,7 @@ extern int current_command_line_count, saved_command_line_count; extern int last_command_exit_value; extern int array_needs_making; extern int posixly_correct, no_symbolic_links; +extern int sigalrm_seen; extern char *current_prompt_string, *ps1_prompt; extern STRING_INT_ALIST word_token_alist[]; extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; @@ -4249,8 +4250,9 @@ bash_event_hook () { /* If we're going to longjmp to top_level, make sure we clean up readline. check_signals will call QUIT, which will eventually longjmp to top_level, - calling run_interrupt_trap along the way. */ - if (interrupt_state) + calling run_interrupt_trap along the way. The check for sigalrm_seen is + to clean up the read builtin's state. */ + if (interrupt_state || sigalrm_seen) rl_cleanup_after_signal (); bashline_reset_event_hook (); check_signals_and_traps (); /* XXX */ diff --git a/builtins/read.def b/builtins/read.def index 56945b95..43971544 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -442,7 +442,10 @@ read_builtin (list) add_unwind_protect (reset_alarm, (char *)NULL); #if defined (READLINE) if (edit) - add_unwind_protect (reset_attempted_completion_function, (char *)NULL); + { + add_unwind_protect (reset_attempted_completion_function, (char *)NULL); + add_unwind_protect (bashline_reset_event_hook, (char *)NULL); + } #endif falarm (tmsec, tmusec); } @@ -1021,6 +1024,7 @@ edit_line (p, itext) old_attempted_completion_function = rl_attempted_completion_function; rl_attempted_completion_function = (rl_completion_func_t *)NULL; + bashline_set_event_hook (); if (itext) { old_startup_hook = rl_startup_hook; @@ -1032,6 +1036,7 @@ edit_line (p, itext) rl_attempted_completion_function = old_attempted_completion_function; old_attempted_completion_function = (rl_completion_func_t *)NULL; + bashline_reset_event_hook (); if (ret == 0) return ret; diff --git a/lib/glob/gmisc.c b/lib/glob/gmisc.c index 7e97e70a..96b1bc08 100644 --- a/lib/glob/gmisc.c +++ b/lib/glob/gmisc.c @@ -388,7 +388,7 @@ glob_dirscan (pat, dirsep) { char *p, *d, *pe, *se; - d = pe = 0; + d = pe = se = 0; for (p = pat; p && *p; p++) { if (extglob_pattern_p (p)) diff --git a/lib/readline/input.c b/lib/readline/input.c index ea701a84..0e5b90e6 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -537,8 +537,16 @@ rl_getc (stream) return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM) return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); + /* keyboard-generated signals of interest */ else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) RL_CHECK_SIGNALS (); + /* non-keyboard-generated signals of interest */ + else if (_rl_caught_signal == SIGALRM +#if defined (SIGVTALRM) + || _rl_caught_signal == SIGVTALRM +#endif + ) + RL_CHECK_SIGNALS (); if (rl_signal_event_hook) (*rl_signal_event_hook) (); diff --git a/tests/shopt.right b/tests/shopt.right index 0a7edfb1..95030523 100644 --- a/tests/shopt.right +++ b/tests/shopt.right @@ -24,8 +24,8 @@ shopt -u extglob shopt -s extquote shopt -u failglob shopt -s force_fignore -shopt -u globstar shopt -u globasciiranges +shopt -u globstar shopt -u gnu_errfmt shopt -u histappend shopt -u histreedit @@ -81,8 +81,8 @@ shopt -u execfail shopt -u extdebug shopt -u extglob shopt -u failglob -shopt -u globstar shopt -u globasciiranges +shopt -u globstar shopt -u gnu_errfmt shopt -u histappend shopt -u histreedit @@ -117,8 +117,8 @@ execfail off extdebug off extglob off failglob off -globstar off globasciiranges off +globstar off gnu_errfmt off histappend off histreedit off @@ -548,7 +548,6 @@ void queue_sigchld_trap (nchild) int nchild; { -itrace("queue_sigchld_trap: %d", nchild); if (nchild > 0) { catch_flag = 1; diff --git a/variables.c b/variables.c index 70fac3bd..69676b47 100644 --- a/variables.c +++ b/variables.c @@ -83,6 +83,11 @@ #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') +/* flags for find_variable_internal */ + +#define FV_FORCETEMPENV 0x01 +#define FV_SKIPINVISIBLE 0x02 + extern char **environ; /* Variables used here and defined in other files. */ @@ -1795,16 +1800,18 @@ var_lookup (name, vcontext) */ SHELL_VAR * -find_variable_internal (name, force_tempenv) +find_variable_internal (name, flags) const char *name; - int force_tempenv; + int flags; { SHELL_VAR *var; - int search_tempenv; + int search_tempenv, force_tempenv; VAR_CONTEXT *vc; var = (SHELL_VAR *)NULL; + force_tempenv = (flags & FV_FORCETEMPENV); + /* If explicitly requested, first look in the temporary environment for the variable. This allows constructs such as "foo=x eval 'echo $foo'" to get the `exported' value of $foo. This happens if we are executing @@ -1815,22 +1822,24 @@ find_variable_internal (name, force_tempenv) if (search_tempenv && temporary_env) var = hash_lookup (name, temporary_env); - vc = shell_variables; -#if 0 -if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */ - expanding_redir && - (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin)) - { - itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV"); - while (vc && (vc->flags & VC_BLTNENV)) - vc = vc->down; - if (vc == 0) - vc = shell_variables; - } -#endif - if (var == 0) - var = var_lookup (name, vc); + { + if ((flags & FV_SKIPINVISIBLE) == 0) + var = var_lookup (name, shell_variables); + else + { + /* essentially var_lookup expanded inline so we can check for + att_invisible */ + for (vc = shell_variables; vc; vc = vc->down) + { + var = hash_lookup (name, vc->table); + if (var && invisible_p (var)) + var = 0; + if (var) + break; + } + } + } if (var == 0) return ((SHELL_VAR *)NULL); @@ -1844,7 +1853,7 @@ SHELL_VAR * find_variable_nameref (v) SHELL_VAR *v; { - int level; + int level, flags; char *newname; SHELL_VAR *orig, *oldv; @@ -1859,7 +1868,10 @@ find_variable_nameref (v) if (newname == 0 || *newname == '\0') return ((SHELL_VAR *)0); oldv = v; - v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))); + flags = 0; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (newname, flags); if (v == orig || v == oldv) { internal_warning (_("%s: circular name reference"), orig->name); @@ -1876,7 +1888,7 @@ find_variable_last_nameref (name) { SHELL_VAR *v, *nv; char *newname; - int level; + int level, flags; nv = v = find_variable_noref (name); level = 0; @@ -1889,7 +1901,10 @@ find_variable_last_nameref (name) if (newname == 0 || *newname == '\0') return ((SHELL_VAR *)0); nv = v; - v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))); + flags = 0; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (newname, flags); } return nv; } @@ -2010,7 +2025,7 @@ find_variable_tempenv (name) { SHELL_VAR *var; - var = find_variable_internal (name, 1); + var = find_variable_internal (name, FV_FORCETEMPENV); if (var && nameref_p (var)) var = find_variable_nameref (var); return (var); @@ -2081,9 +2096,52 @@ find_variable (name) const char *name; { SHELL_VAR *v; + int flags; last_table_searched = 0; - v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))); + flags = 0; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (name, flags); + if (v && nameref_p (v)) + v = find_variable_nameref (v); + return v; +} + +/* Find the first instance of NAME in the variable context chain; return first + one found without att_invisible set; return 0 if no non-invisible instances + found. */ +SHELL_VAR * +find_variable_no_invisible (name) + const char *name; +{ + SHELL_VAR *v; + int flags; + + last_table_searched = 0; + flags = FV_SKIPINVISIBLE; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (name, flags); + if (v && nameref_p (v)) + v = find_variable_nameref (v); + return v; +} + +/* Find the first instance of NAME in the variable context chain; return first + one found even if att_invisible set. */ +SHELL_VAR * +find_variable_for_assignment (name) + const char *name; +{ + SHELL_VAR *v; + int flags; + + last_table_searched = 0; + flags = 0; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (name, flags); if (v && nameref_p (v)) v = find_variable_nameref (v); return v; @@ -2094,8 +2152,12 @@ find_variable_noref (name) const char *name; { SHELL_VAR *v; + int flags; - v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))); + flags = 0; + if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) + flags |= FV_FORCETEMPENV; + v = find_variable_internal (name, flags); return v; } @@ -2197,10 +2259,7 @@ make_local_variable (name) /* local foo; local foo; is a no-op. */ old_var = find_variable (name); if (old_var && local_p (old_var) && old_var->context == variable_context) - { - VUNSETATTR (old_var, att_invisible); /* XXX */ - return (old_var); - } + return (old_var); was_tmpvar = old_var && tempvar_p (old_var); /* If we're making a local variable in a shell function, the temporary env @@ -2279,7 +2338,7 @@ make_local_variable (name) if (ifsname (name)) setifs (new_var); - if (was_tmpvar == 0) + if (was_tmpvar == 0 && no_invisible_vars == 0) VSETATTR (new_var, att_invisible); /* XXX */ return (new_var); } diff --git a/variables.h b/variables.h index 1a783b92..64677028 100644 --- a/variables.h +++ b/variables.h @@ -250,6 +250,8 @@ extern SHELL_VAR *find_global_variable __P((const char *)); extern SHELL_VAR *find_global_variable_noref __P((const char *)); extern SHELL_VAR *find_shell_variable __P((const char *)); extern SHELL_VAR *find_tempenv_variable __P((const char *)); +extern SHELL_VAR *find_variable_no_invisible __P((const char *)); +extern SHELL_VAR *find_variable_for_assignment __P((const char *)); extern SHELL_VAR *copy_variable __P((SHELL_VAR *)); extern SHELL_VAR *make_local_variable __P((const char *)); extern SHELL_VAR *bind_variable __P((const char *, char *, int)); |