mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 00:19:51 +02:00
commit bash-20180504 snapshot
This commit is contained in:
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user