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
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;
{
/* 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 */
#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. */
*/
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
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);
find_variable_nameref (v)
SHELL_VAR *v;
{
- int level;
+ int level, flags;
char *newname;
SHELL_VAR *orig, *oldv;
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);
{
SHELL_VAR *v, *nv;
char *newname;
- int level;
+ int level, flags;
nv = v = find_variable_noref (name);
level = 0;
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;
}
{
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);
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;
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;
}
/* 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
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);
}