commit bash-20180504 snapshot

This commit is contained in:
Chet Ramey
2018-05-08 14:27:28 -04:00
parent 2afeb2af6a
commit 96b7e26874
13 changed files with 190 additions and 45 deletions
+40
View File
@@ -15318,3 +15318,43 @@ subst.c
to the flags passed to quote_string_for_globbing. Same issue as the
one with `case' fixed on 4/7, report from Martijn Dekker
<martijn@inlv.org>
4/30
----
redir.c
- do_redirection_internal: r_close_this: if the file descriptor is
already closed before the shell is asked to close it, make sure to
add an undo list redirect to make sure it stays closed. Report from
Martijn Dekker <martijn@inlv.org>
5/2
---
variables.c
- push_posix_temp_var: new function, takes the SHELL_VAR * passed as
an argument and uses the name and value to create a global variable
- merge_temporary_env: if posixly_correct is set, call
push_posix_temp_var to create global variables, otherwise call
push_temp_var to preserve the old behavior. Right now, it's only
called when in posix mode, but that might change. This undoes the
change from 4/27 when in posix mode
5/3
---
sig.c
- struct that holds the terminating signal information has a new
field: whether that signal is expected to cause a core dump
- termsig_handler: if the call to kill(2) doesn't kill the process,
we have a problem. If our pid is not 1, we just exit with status
128+sig (fake the sig exit status). If the pid is 1, we assume
we're in a Linux pid namespace and aren't allowed to send a signal
to ourselves. If we need to generate a core dump, we try to get
the kernel to SIGSEGV us by dereferencing location 0. If not, we
just exit with 128+sig. From a report and patch from Andrei Vagin
<avagin@virtuozzo.com>
5/4
---
bashline.c
- bash_execute_unix_command: make sure that parse_and_execute is called
with newly-allocated memory to avoid prematurely freeing the
command. Report and fix from Koichi Murase <myoga.murase@gmail.com>
+1 -1
View File
@@ -4147,7 +4147,7 @@ bash_execute_unix_command (count, key)
array_needs_making = 1;
save_parser_state (&ps);
r = parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
restore_parser_state (&ps);
v = find_variable ("READLINE_LINE");
+1 -1
View File
@@ -31,7 +31,7 @@ as a shell function, but need to execute the builtin within the function.
Exit Status:
Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is
not a shell builtin..
not a shell builtin.
$END
#include <config.h>
+1 -1
View File
@@ -6065,7 +6065,7 @@ as the sole input. If set, the value denotes the number
of consecutive @code{EOF} characters that can be read as the
first character on an input line
before the shell will exit. If the variable exists but does not
have a numeric value (or has no value) then the default is 10.
have a numeric value, or has no value, then the default is 10.
If the variable does not exist, then @code{EOF} signifies the end of
input to the shell. This is only in effect for interactive shells.
+5 -2
View File
@@ -1142,9 +1142,12 @@ do_redirection_internal (redirect, flags)
r = 0;
/* XXX - only if REDIR_VARASSIGN not set? */
if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
if (flags & RX_UNDOABLE)
{
r = add_undo_redirect (redirector, ri, -1);
if (fcntl (redirector, F_GETFD, 0) != -1)
r = add_undo_redirect (redirector, ri, -1);
else
r = add_undo_close_redirect (redirector);
REDIRECTION_ERROR (r, errno, redirector);
}
+45 -12
View File
@@ -1,6 +1,6 @@
/* sig.c - interface for shell signal handlers and signal initialization. */
/* Copyright (C) 1994-2015 Free Software Foundation, Inc.
/* Copyright (C) 1994-2018 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -113,6 +113,7 @@ struct termsig {
int signum;
SigHandler *orig_handler;
int orig_flags;
int core_dump;
};
#define NULL_HANDLER (SigHandler *)SIG_DFL
@@ -130,15 +131,15 @@ static struct termsig terminating_signals[] = {
#endif
#ifdef SIGILL
{ SIGILL, NULL_HANDLER, 0 },
{ SIGILL, NULL_HANDLER, 0, 1},
#endif
#ifdef SIGTRAP
{ SIGTRAP, NULL_HANDLER, 0 },
{ SIGTRAP, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGIOT
{ SIGIOT, NULL_HANDLER, 0 },
{ SIGIOT, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGDANGER
@@ -150,19 +151,19 @@ static struct termsig terminating_signals[] = {
#endif
#ifdef SIGFPE
{ SIGFPE, NULL_HANDLER, 0 },
{ SIGFPE, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGBUS
{ SIGBUS, NULL_HANDLER, 0 },
{ SIGBUS, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGSEGV
{ SIGSEGV, NULL_HANDLER, 0 },
{ SIGSEGV, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGSYS
{ SIGSYS, NULL_HANDLER, 0 },
{ SIGSYS, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGPIPE
@@ -177,12 +178,14 @@ static struct termsig terminating_signals[] = {
{ SIGTERM, NULL_HANDLER, 0 },
#endif
/* These don't generate core dumps on anything but Linux, but we're doing
this just for Linux anyway. */
#ifdef SIGXCPU
{ SIGXCPU, NULL_HANDLER, 0 },
{ SIGXCPU, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGXFSZ
{ SIGXFSZ, NULL_HANDLER, 0 },
{ SIGXFSZ, NULL_HANDLER, 0, 1 },
#endif
#ifdef SIGVTALRM
@@ -213,6 +216,7 @@ static struct termsig terminating_signals[] = {
#define XSIG(x) (terminating_signals[x].signum)
#define XHANDLER(x) (terminating_signals[x].orig_handler)
#define XSAFLAGS(x) (terminating_signals[x].orig_flags)
#define XCOREDUMP(x) (terminating_signals[x].core_dump)
static int termsigs_initialized = 0;
@@ -360,7 +364,6 @@ reset_terminating_signals ()
termsigs_initialized = 0;
}
#undef XSIG
#undef XHANDLER
/* Run some of the cleanups that should be performed when we run
@@ -542,6 +545,8 @@ termsig_handler (sig)
int sig;
{
static int handling_termsig = 0;
int i, core;
sigset_t mask;
/* Simple semaphore to keep this function from being executed multiple
times. Since we no longer are running as a signal handler, we don't
@@ -583,11 +588,39 @@ termsig_handler (sig)
executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0;
run_exit_trap (); /* XXX - run exit trap possibly in signal context? */
/* We don't change the set of blocked signals. If a user starts the shell
with a terminating signal blocked, we won't get here (and if by some
magic chance we do, we'll exit below). */
set_signal_handler (sig, SIG_DFL);
kill (getpid (), sig);
exit (1); /* just in case the kill fails? */
if (dollar_dollar_pid != 1)
exit (128+sig); /* just in case the kill fails? */
/* We are PID 1, and the kill above failed to kill the process. We assume
this means that we are running as an init process in a pid namespace
on Linux. In this case, we can't send ourselves a fatal signal, so we
determine whether or not we should have generated a core dump with the
kill call and attempt to trick the kernel into generating one if
necessary. */
sigprocmask (SIG_SETMASK, (sigset_t *)NULL, &mask);
for (i = core = 0; i < TERMSIGS_LENGTH; i++)
{
set_signal_handler (XSIG (i), SIG_DFL);
sigdelset (&mask, XSIG (i));
if (sig == XSIG (i))
core = XCOREDUMP (i);
}
sigprocmask (SIG_SETMASK, &mask, (sigset_t *)NULL);
if (core)
*((volatile unsigned long *) NULL) = 0xdead0000 + sig; /* SIGSEGV */
exit (128+sig);
}
#undef XSIG
/* What we really do when SIGINT occurs. */
sighandler
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+11 -11
View File
@@ -3,7 +3,7 @@ foo
test2
test3
test4
8
8
test5
test6
test7
@@ -15,15 +15,15 @@ bye
l8r
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
intern
1
0
0
0
0
1
0
0
0
0
extern
1
0
0
0
0
1
0
0
0
0
123
+11 -7
View File
@@ -1,4 +1,5 @@
# process substitution constructs that have caused problems in the past
. ./test-glue-functions
eval cat <(echo test1)
eval "echo foo;cat" <(echo test2)
@@ -13,7 +14,7 @@ unset f
FN=$TMPDIR/bashtest-procsub-$$
cat >"$FN" <<EOF
echo "test 12" | wc -c
echo "test 12" | wc -c | _cut_leading_spaces
cat "\$1"
EOF
@@ -44,10 +45,8 @@ f2 <(echo l8r)
unset -f f1 f2
moo() { ls -l "$1" >/dev/null; ls -l "$1" >/dev/null; }; moo >(true)
moo() { ls -al "$1" >/dev/null; (true); ls -al "$1" >/dev/null; }; moo >(true)
unset -f moo
# set up conditions for test
ulimit -n 256
bug()
{
@@ -76,7 +75,7 @@ count_lines()
}
echo intern
count_lines <(date)
count_lines <(date) | _cut_leading_spaces
unset -f count_lines
echo extern
@@ -89,7 +88,12 @@ true | wc -l < \$1
wc -l < \$1
EOF
${THIS_SH} -c "source $FN <(date)"
${THIS_SH} -c "source $FN <(date)" | _cut_leading_spaces
rm -f $FN
moo() { ls -l "$1" >/dev/null; ls -l "$1" >/dev/null; }; moo >(true)
moo() { ls -al "$1" >/dev/null; (true); ls -al "$1" >/dev/null; }; moo >(true)
unset -f moo
${THIS_SH} ./procsub1.sub
+5 -1
View File
@@ -6,4 +6,8 @@ _intl_normalize_spaces()
sed -e 's/[[:space:]]\{1,\}/ /g' -e 's/[[:space:]]*$//'
}
# avoid whitespace differences in wc implementations
_cut_leading_spaces()
{
sed -e 's/^[[:space:]]*//g'
}
+1
View File
@@ -135,6 +135,7 @@ declare -a bar=([0]="zero" [1]="one")
declare -A foo=([one]="one" [zero]="zero" )
declare -a bar=([0]="zero" [1]="one")
./varenv11.sub: line 29: a: readonly variable
foo=abc
a=z
a=b
a=z
+67 -8
View File
@@ -280,6 +280,7 @@ static SHELL_VAR *find_variable_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *,
static SHELL_VAR *find_variable_last_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
static void push_posix_temp_var __P((PTR_T));
static void push_temp_var __P((PTR_T));
static void propagate_temp_var __P((PTR_T));
static void dispose_temporary_env __P((sh_free_func_t *));
@@ -4243,8 +4244,46 @@ find_tempenv_variable (name)
char **tempvar_list;
int tvlist_ind;
/* Take a variable from an assignment statement preceding a posix special
builtin (including `return') and create a global variable from it. This
is called from merge_temporary_env, which is only called when in posix
mode. */
static void
push_posix_temp_var (data)
PTR_T data;
{
SHELL_VAR *var, *v;
HASH_TABLE *binding_table;
var = (SHELL_VAR *)data;
binding_table = global_variables->table;
if (binding_table == 0)
binding_table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
/* global variables are no longer temporary and don't need propagating. */
var->attributes &= ~(att_tempvar|att_propagate);
if (v)
v->attributes |= var->attributes;
if (find_special_var (var->name) >= 0)
tempvar_list[tvlist_ind++] = savestring (var->name);
dispose_variable (var);
}
/* Push the variable described by (SHELL_VAR *)DATA down to the next
variable context from the temporary environment. */
variable context from the temporary environment. This can be called
from one context:
1. propagate_temp_var: which is called to propagate variables in
assignments like `var=value declare -x var' to the surrounding
scope.
In this case, the variable should have the att_propagate flag set and
we can create variables in the current scope.
*/
static void
push_temp_var (data)
PTR_T data;
@@ -4267,7 +4306,7 @@ push_temp_var (data)
v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
/* XXX - should we set the context here? It shouldn't matter because of how
assign_in_env works, but might want to check. */
assign_in_env works, but we do it anyway. */
if (v)
v->context = shell_variables->scope;
@@ -4288,6 +4327,10 @@ push_temp_var (data)
dispose_variable (var);
}
/* Take a variable described by DATA and push it to the surrounding scope if
the PROPAGATE attribute is set. That gets set by push_temp_var if we are
taking a variable like `var=value declare -x var' and propagating it to
the enclosing scope. */
static void
propagate_temp_var (data)
PTR_T data;
@@ -4351,12 +4394,15 @@ dispose_used_env_vars ()
}
/* Take all of the shell variables in the temporary environment HASH_TABLE
and make shell variables from them at the current variable context. */
and make shell variables from them at the current variable context.
Right now, this is only called in Posix mode to implement the historical
accident of creating global variables from assignment statements preceding
special builtins, but we check in case this acquires another caller later. */
void
merge_temporary_env ()
{
if (temporary_env)
dispose_temporary_env (push_temp_var);
dispose_temporary_env (posixly_correct ? push_posix_temp_var : push_temp_var);
}
void
@@ -4859,6 +4905,16 @@ push_var_context (name, flags, tempvars)
return (shell_variables = vc);
}
/* This can be called from one of two code paths:
1. pop_scope, which implements the posix rules for propagating variable
assignments preceding special builtins to the surrounding scope.
2. pop_var_context, which is called from pop_context and implements the
posix rules for propagating variable assignments preceding function
calls to the surrounding scope.
It takes variables out of a temporary environment hash table. We take the
variable in data
*/
static void
push_func_var (data)
PTR_T data;
@@ -4978,11 +5034,7 @@ push_exported_var (data)
propagated, bind it in the previous scope before disposing it. */
/* XXX - This isn't exactly right, because all tempenv variables have the
export attribute set. */
#if 0
if (exported_p (var) || (var->attributes & att_propagate))
#else
if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
#endif
{
var->attributes &= ~att_tempvar; /* XXX */
v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
@@ -5000,11 +5052,17 @@ push_exported_var (data)
dispose_variable (var);
}
/* This is called to propagate variables in the temporary environment of a
special builtin (if IS_SPECIAL != 0) or exported variables that are the
result of a builtin like `source' or `command' that can operate on the
variables in its temporary environment. In the first case, we call
push_func_var, which does the right thing (for now) */
void
pop_scope (is_special)
int is_special;
{
VAR_CONTEXT *vcxt, *ret;
int is_bltinenv;
vcxt = shell_variables;
if (vc_istempscope (vcxt) == 0)
@@ -5012,6 +5070,7 @@ pop_scope (is_special)
internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
return;
}
is_bltinenv = vc_isbltnenv (vcxt); /* XXX - for later */
ret = vcxt->down;
if (ret)
+1
View File
@@ -157,6 +157,7 @@ typedef struct _vlist {
#define regen_p(var) ((((var)->attributes) & (att_regenerate)))
#define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
#define propagate_p(var) ((((var)->attributes) & (att_propagate)))
/* Variable names: lvalues */
#define name_cell(var) ((var)->name)