commit bash-20130411 snapshot

This commit is contained in:
Chet Ramey
2013-05-06 08:40:23 -04:00
parent 21af69d5ba
commit a37d979e7b
27 changed files with 6755 additions and 22 deletions
+45 -1
View File
@@ -4406,7 +4406,7 @@ execute_cmd.c
- execute_command_internal: make sure any subshell forked to run a
group command or user subshell at the end of a pipeline runs any
EXIT trap it sets. Fixes debian bash bug 698411
http://bugs.debian.org/cgi-big/bugreport.cgi?bug=698411
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411
subst.c
- shell_expand_word_list: fix code that creates args for and calls
@@ -4858,3 +4858,47 @@ subst.c
It doesn't work to just turn on the DQUOTE flag, since that means
that things like ${x["expression"]} are not expanded correctly.
Fixes problem pointed out by Dan Douglas <ormaaj@gmail.com>
4/13
----
subst.c
- process_substitute: run the EXIT trap before exiting, as other
shells seem to. Fixes problem pointed out by Dan Douglas
<ormaaj@gmail.com>
lib/readline/readline.c
- readline_internal_setup: call rl_vi_insertion_mode to enter vi
mode instead of rl_vi_insert_mode to avoid resetting the saved last
command information. Posix says that `.' can repeat a command
that was entered on a previous line so we need to save the info.
Fixes bug reported by Ian A. Watson <watson_ian_a@lilly.com>
4/14
----
lib/readline/complete.c
- rl_completion_matches: make sure xrealloc returns something non-null
(can happen when interrupted by a signal) before trying to add
matches to match_list
subst.c
- array_remove_pattern: return NULL right away if array_variable_part
returns an invisible variable
- array_length_reference: handle array_variable_part returning an
invisible variable
- get_var_and_type: handle array_variable_part returning an invisible
variable
4/15
----
execute_cmd.c
- execute_command_internal: make sure to run the EXIT trap for group
commands anywhere in pipelines, not just at the end. From a point
raised by Andreas Schwab <schwab@linux-m68k.org>
variables.c
- bind_int_variable: make sure invisible flag is unset. Fixes problems
like "declare -ai a; : $(( a[4]=4 ));"
arrayfunc.c
- array_variable_part: return variable even if invisible flag set,
callers must handle invisible vars
+54 -1
View File
@@ -4406,7 +4406,7 @@ execute_cmd.c
- execute_command_internal: make sure any subshell forked to run a
group command or user subshell at the end of a pipeline runs any
EXIT trap it sets. Fixes debian bash bug 698411
http://bugs.debian.org/cgi-big/bugreport.cgi?bug=698411
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411
subst.c
- shell_expand_word_list: fix code that creates args for and calls
@@ -4848,3 +4848,56 @@ variables.c
merged (in execute_function) into the list of variable contexts the
function sees as shell_variables by the time this is called. Fixes
inconsistency pointed out by Dan Douglas <ormaaj@gmail.com>
subst.c
- expand_arith_string: expanded out contents of expand_string,
expand_string_internal, expand_string_if_necessary to create a
WORD_DESC and call call_expand_word_internal() on it directly.
We don't want process substitution to be performed ( 1<(2) ) should
mean something different in an arithmetic expression context.
It doesn't work to just turn on the DQUOTE flag, since that means
that things like ${x["expression"]} are not expanded correctly.
Fixes problem pointed out by Dan Douglas <ormaaj@gmail.com>
4/13
----
subst.c
- process_substitute: run the EXIT trap before exiting, as other
shells seem to. Fixes problem pointed out by Dan Douglas
<ormaaj@gmail.com>
lib/readline/readline.c
- readline_internal_setup: call rl_vi_insertion_mode to enter vi
mode instead of rl_vi_insert_mode to avoid resetting the saved last
command information. Posix says that `.' can repeat a command
that was entered on a previous line so we need to save the info.
Fixes bug reported by Ian A. Watson <watson_ian_a@lilly.com>
4/14
----
lib/readline/complete.c
- rl_completion_matches: make sure xrealloc returns something non-null
(can happen when interrupted by a signal) before trying to add
matches to match_list
subst.c
- array_remove_pattern: return NULL right away if array_variable_part
returns an invisible variable
- array_length_reference: handle array_variable_part returning an
invisible variable
- get_var_and_type: handle array_variable_part returning an invisible
variable
4/15
----
execute_cmd.c
- execute_command_internal: make sure to run the EXIT trap for group
commands anywhere in pipelines, not just at the end. From a point
raised by Andreas Schwab <schwab@linux-m68k.org>
variables.c
- bind_int_variable: make sure invisible flag is unset. Fixes problems
like "declare -ai a; : $(( a[4]=4 ));"
arrayfunc.c
- array_variable_part: return variable even if invisible flag set
+2
View File
@@ -826,6 +826,7 @@ tests/source5.sub f
tests/source6.sub f
tests/case.tests f
tests/case.right f
tests/case1.sub f
tests/casemod.tests f
tests/casemod.right f
tests/comsub.tests f
@@ -1164,6 +1165,7 @@ tests/trap2.sub f 755
tests/trap2a.sub f 755
tests/trap3.sub f
tests/trap4.sub f
tests/trap5.sub f
tests/type.tests f
tests/type.right f
tests/type1.sub f
+1247
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -929,7 +929,11 @@ 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() \
+1 -1
View File
@@ -852,7 +852,7 @@ array_expand_index (var, s, len)
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
t = expand_arith_string (exp, Q_DOUBLE_QUOTES);
t = expand_arith_string (exp, 0);
this_command_name = (char *)NULL;
val = evalexp (t, &expok);
free (t);
+4 -2
View File
@@ -607,9 +607,11 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
want to note this before execute_in_subshell modifies the
COMMAND struct. Need to keep in mind that execute_in_subshell
runs the exit trap for () subshells itself. */
/* This handles { command; } &
s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous;
/* run exit trap for : | { ...; } and : | ( ... ) */
s += user_subshell == 0 && command->type == cm_group && pipe_in != NO_PIPE && pipe_out == NO_PIPE && asynchronous == 0;
/* run exit trap for : | { ...; } and { ...; } | : */
/* run exit trap for : | ( ...; ) and ( ...; ) | : */
s += user_subshell == 0 && command->type == cm_group && (pipe_in != NO_PIPE || pipe_out != NO_PIPE) && asynchronous == 0;
last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close);
if (s)
+4 -8
View File
@@ -607,10 +607,12 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
want to note this before execute_in_subshell modifies the
COMMAND struct. Need to keep in mind that execute_in_subshell
runs the exit trap for () subshells itself. */
/* This handles { command; } &
s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous;
/* run exit trap for : | { ...; } and : | ( ... ) */
s += user_subshell == 0 && command->type == cm_group && pipe_in != NO_PIPE && pipe_out == NO_PIPE && asynchronous == 0;
s += user_subshell == 0 && command->type == cm_group && (pipe_in != NO_PIPE || pipe_out != NO_PIPE) && asynchronous == 0;
itrace("calling execute_in_subshell: s = %d", s);
last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close);
if (s)
subshell_exit (last_command_exit_value);
@@ -3423,7 +3425,7 @@ execute_arith_command (arith_command)
{
int expok, save_line_number, retval;
intmax_t expresult;
WORD_LIST *new, *w;
WORD_LIST *new;
char *exp;
expresult = 0;
@@ -3458,12 +3460,6 @@ execute_arith_command (arith_command)
}
#endif
for (w = arith_command->exp; w; w = w->next)
{
if (w->word)
w->word->flags |= W_NOPROCSUB;
}
new = expand_words_no_vars (arith_command->exp);
/* If we're tracing, make a new word list with `((' at the front and `))'
+5 -1
View File
@@ -2132,13 +2132,17 @@ rl_completion_matches (text, entry_function)
xfree (match_list);
match_list = 0;
match_list_size = 0;
matches = 0;
RL_CHECK_SIGNALS ();
}
if (matches + 1 == match_list_size)
if (matches + 1 >= match_list_size)
match_list = (char **)xrealloc
(match_list, ((match_list_size += 10) + 1) * sizeof (char *));
if (match_list == 0)
return (match_list);
match_list[++matches] = string;
match_list[matches + 1] = (char *)NULL;
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -406,7 +406,7 @@ readline_internal_setup ()
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_vi_insert_mode (1, 'i');
rl_vi_insertion_mode (1, 'i'); /* don't want to reset last */
#endif /* VI_MODE */
/* If we're not echoing, we still want to at least print a prompt, because
+1 -2
View File
@@ -821,7 +821,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
rl_dispatching = 1;
RL_SETSTATE(RL_STATE_DISPATCHING);
(*func) (rl_numeric_arg * rl_arg_sign, key);
r = (*func) (rl_numeric_arg * rl_arg_sign, key);
RL_UNSETSTATE(RL_STATE_DISPATCHING);
rl_dispatching = 0;
@@ -959,7 +959,6 @@ _rl_dispatch_subseq (key, map, got_subseq)
key != ANYOTHERKEY &&
rl_key_sequence_length == 1 && /* XXX */
_rl_vi_textmod_command (key))
/* This breaks when using arrow keys to move within line */
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
File diff suppressed because it is too large Load Diff
+15 -2
View File
@@ -4511,6 +4511,11 @@ array_remove_pattern (var, pattern, patspec, varname, quoted)
/* compute itype from varname here */
v = array_variable_part (varname, &ret, 0);
/* XXX */
if (v && invisible_p (var))
return ((char *)NULL);
itype = ret[0];
a = (v && array_p (v)) ? array_cell (v) : 0;
@@ -5160,6 +5165,8 @@ process_substitute (string, open_for_read_in_child)
close (open_for_read_in_child ? 0 : 1);
#endif /* !HAVE_DEV_FD */
last_command_exit_value = result;
result = run_exit_trap ();
exit (result);
/*NOTREACHED*/
}
@@ -5524,7 +5531,7 @@ array_length_reference (s)
/* If unbound variables should generate an error, report one and return
failure. */
if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
if ((var == 0 || invisible_p (var) || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
{
c = *--t;
*t = '\0';
@@ -5533,7 +5540,7 @@ array_length_reference (s)
*t = c;
return (-1);
}
else if (var == 0)
else if (var == 0 || invisible_p (var))
return 0;
/* We support a couple of expansions for variables that are not arrays.
@@ -6316,6 +6323,12 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
/* If we want to signal array_value to use an already-computed index,
set LIND to that index */
lind = (ind != INTMAX_MIN && (flags & AV_USEIND)) ? ind : 0;
if (v && invisible_p (v))
{
vtype = VT_ARRAYMEMBER;
*varp = (SHELL_VAR *)NULL;
*valp = (char *)NULL;
}
if (v && (array_p (v) || assoc_p (v)))
{ /* [ */
if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
+17 -3
View File
@@ -3150,7 +3150,8 @@ expand_arith_string (string, quoted)
if (string[i])
{
/* This is expanded version of expand_string_internal */
/* This is expanded version of expand_string_internal as it's called by
expand_string_leave_quoted */
td.flags = W_NOPROCSUB; /* don't want process substitution */
td.word = savestring (string);
list = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
@@ -4510,6 +4511,11 @@ array_remove_pattern (var, pattern, patspec, varname, quoted)
/* compute itype from varname here */
v = array_variable_part (varname, &ret, 0);
/* XXX */
if (v && invisible_p (var))
return ((char *)NULL);
itype = ret[0];
a = (v && array_p (v)) ? array_cell (v) : 0;
@@ -5159,6 +5165,8 @@ process_substitute (string, open_for_read_in_child)
close (open_for_read_in_child ? 0 : 1);
#endif /* !HAVE_DEV_FD */
last_command_exit_value = result;
result = run_exit_trap ();
exit (result);
/*NOTREACHED*/
}
@@ -5523,7 +5531,7 @@ array_length_reference (s)
/* If unbound variables should generate an error, report one and return
failure. */
if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
if ((var == 0 || invisible_p (var) || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
{
c = *--t;
*t = '\0';
@@ -5532,7 +5540,7 @@ array_length_reference (s)
*t = c;
return (-1);
}
else if (var == 0)
else if (var == 0 || invisible_p (var))
return 0;
/* We support a couple of expansions for variables that are not arrays.
@@ -6315,6 +6323,12 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
/* If we want to signal array_value to use an already-computed index,
set LIND to that index */
lind = (ind != INTMAX_MIN && (flags & AV_USEIND)) ? ind : 0;
if (v && invisible_p (var))
{
vtype = VT_ARRAYMEMBER;
*varp = (SHELL_VAR *)NULL;
*valp = (char *)NULL;
}
if (v && (array_p (v) || assoc_p (v)))
{ /* [ */
if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
+11
View File
@@ -7,3 +7,14 @@ no more clauses
1.0
./case.tests: line 29: xx: readonly variable
1.1
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
mysterious 1
mysterious 2
+3
View File
@@ -28,3 +28,6 @@ unset x
readonly xx=1
case 1 in $((xx++)) ) echo hi1 ;; *) echo hi2; esac
echo ${xx}.$?
# tests of quote removal and pattern matching
${THIS_SH} ./case1.sub
+30
View File
@@ -0,0 +1,30 @@
case foo in
bar) echo skip ;;
foo) echo fallthrough ;&
bax) echo to here ;&
qux) echo and here;;
fop) echo but not here;;
esac
case foobar in
bar) echo skip ;;
foo*) echo retest ;;&
*bar) echo and match ;;&
qux) echo but not this ;;
esac
case a in
a) echo no more clauses;&
esac
x=0 y=1
case 1 in
$((y=0)) ) ;;
$((x=1)) ) ;&
$((x=2)) ) echo $x.$y ;;
esac
unset x
readonly xx=1
case 1 in $((xx++)) ) echo hi1 ;; *) echo hi2; esac
echo ${xx}.$?
+64
View File
@@ -0,0 +1,64 @@
x='\x'
case x in
\x) echo ok 1;;
*) echo bad 1;;
esac
case x in
$x) echo ok 2;;
*) echo bad 2;;
esac
case $x in
\x) echo bad 3;;
\\x) echo ok 3 ;;
*) echo bad 3.1 ;;
esac
case $x in
\\$x) echo ok 4 ;;
x) echo bad 4;;
$x) echo bad 4.1 ;;
*) echo bad 4.2;;
esac
case x in
\\x) echo bad 5;;
\x) echo ok 5;;
*) echo bad 5.1;;
esac
case x in
\\x) echo bad 6;;
x) echo ok 6;;
*) echo bad 6.1;;
esac
case x in
$x) echo ok 7 ;;
\\$x) echo bad 7 ;;
*) echo bad 7.1 ;;
esac
case x in
\x) echo ok 8 ;;
\\x) echo bad 8 ;;
*) echo bad 8.1 ;;
esac
case \x in
\x) echo ok 9 ;;
\\x) echo bad 9 ;;
*) echo bad 9.1 ;;
esac
case $x in
$x) echo oops 1 ;;
*) echo mysterious 1 ;;
esac
case \x in
\x) echo mysterious 2 ;;
*) echo oops 2 ;;
esac
+18
View File
@@ -85,6 +85,24 @@ outside 1
outside 2
outside 3
outside 4
sleep 2
wait $!
exit
in trap EXIT
sleep 2
wait $!
exit
in trap EXIT
works
bar
bar
foo
trap -- '' SIGINT
trap -- '' SIGUSR2
foo
bar
foo
bar
caught a child death
caught a child death
caught a child death
+2
View File
@@ -70,6 +70,8 @@ ${THIS_SH} ./trap3.sub
${THIS_SH} ./trap4.sub
${THIS_SH} ./trap5.sub
#
# show that setting a trap on SIGCHLD is not disastrous.
#
+94
View File
@@ -0,0 +1,94 @@
# test the trap code
trap 'echo exiting' 0
trap 'echo aborting' 1 2 3 6 15
# make sure a user-specified subshell runs the exit trap, but does not
# inherit the exit trap from a parent shell
( trap 'echo subshell exit' 0; exit 0 )
( exit 0 )
trap
func()
{
trap 'echo ${FUNCNAME:-$0}[$LINENO] funcdebug' DEBUG
echo funcdebug line
}
trap 'echo [$LINENO] debug' DEBUG
echo debug line
trap
func
trap
trap 'echo ${FUNCNAME:-$0}[$LINENO] debug' DEBUG
func2()
{
echo func2debug line
}
declare -ft func2
func2
unset -f func2
trap '' DEBUG
trap
trap - debug
trap
trap - HUP
trap hup
trap '' INT
trap '' int
trap
# exit 0 in exit trap should set exit status
(
set -e
trap 'exit 0' EXIT
false
echo bad
)
echo $?
# hmmm...should this set the handling to SIG_IGN for children, too?
trap '' USR2
./trap1.sub
# test ERR trap
./trap2.sub
${THIS_SH} ./trap3.sub
${THIS_SH} ./trap4.sub
#
# show that setting a trap on SIGCHLD is not disastrous.
#
set -o monitor
trap 'echo caught a child death' SIGCHLD
sleep 7 & sleep 6 & sleep 5 &
# this will only catch the first, since there's a trap on SIGCHLD
wait
trap -p SIGCHLD
# Now reset some of the signals the shell handles specially back to
# their default values (with or without the SIG prefix)
trap - SIGINT QUIT TERM
trap
trap - SIGCHLD
wait
+25
View File
@@ -15,3 +15,28 @@ trap 'echo inherited exit trap' EXIT
: | ( exit; ) | : ; echo outside 4
trap - EXIT
# make sure group commands that are not at the beginning or end of pipelines
# run an EXIT trap, with and without the exit builtin
echo ignored |
{
trap 'echo "in trap EXIT">&2' EXIT
sleep 4 &
echo 'sleep 2'>&2
sleep 2
echo 'wait $!'>&2
wait $!
echo 'exit'>&2
exit
} | cat
echo ignored |
{
trap 'echo "in trap EXIT">&2' EXIT
sleep 4 &
echo 'sleep 2'>&2
sleep 2
echo 'wait $!'>&2
wait $!
echo 'exit'>&2
} | cat
+17
View File
@@ -0,0 +1,17 @@
# make sure subshells at the end of pipelines run any exit traps they set
: | { trap 'echo exit subshell 1' EXIT; exit; }; echo current shell
: | { trap 'echo exit subshell 2' EXIT; exit; }; echo current shell
: | { trap 'echo exit subshell 3' EXIT; exit; } | : ; echo current shell
: | { trap 'echo exit subshell 4' EXIT; exit; } | : ; echo current shell
trap 'echo inherited exit trap' EXIT
: | { exit; } ; echo outside 1
: | ( exit; ) ; echo outside 2
: | { exit; } | : ; echo outside 3
: | ( exit; ) | : ; echo outside 4
trap - EXIT
+18
View File
@@ -0,0 +1,18 @@
# make sure process substitution runs the exit trap
[[ -n $(< <(trap "tee /dev/fd/3" EXIT)) ]] 3>&1 <<<works || echo "fail :("
read foo < <(trap "echo bar" EXIT)
echo $foo
cat <(trap "echo bar" EXIT)
trap "echo bar" EXIT #should proc subst inherit this?
cat <(echo foo ; exit 0;)
trap - 0
trap
cat <(echo foo; trap "echo bar" EXIT)
trap "echo bar" EXIT #should proc subst inherit this?
cat <(echo foo)
+2
View File
@@ -2764,6 +2764,8 @@ bind_int_variable (lhs, rhs)
if (v && isint)
VSETATTR (v, att_integer);
VUNSETATTR (v, att_invisible);
return (v);
}
+3
View File
@@ -1764,6 +1764,8 @@ hash_lookup (name, hashed_vars)
BUCKET_CONTENTS *bucket;
bucket = hash_search (name, hashed_vars, 0);
/* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
table. */
if (bucket)
last_table_searched = hashed_vars;
return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
@@ -2070,6 +2072,7 @@ find_variable (name)
{
SHELL_VAR *v;
last_table_searched = 0;
v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
if (v && nameref_p (v))
v = find_variable_nameref (v);