mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 16:39:53 +02:00
commit bash-20150925 snapshot
This commit is contained in:
@@ -1403,7 +1403,7 @@ y. The {x}<word redirection feature now allows words like {array[ind]} and
|
||||
can use variables with special meanings to the shell (e.g., BASH_XTRACEFD).
|
||||
|
||||
z. There is a new CHILD_MAX special shell variable; its value controls the
|
||||
number of exited child statues the shell remembers.
|
||||
number of exited child statuses the shell remembers.
|
||||
|
||||
aa. There is a new configuration option (--enable-direxpand-default) that
|
||||
causes the `direxpand' shell option to be enabled by default.
|
||||
|
||||
@@ -9656,3 +9656,32 @@ lib/readline/history.c
|
||||
- history_get_time: handle strtol overflows caused by malicious
|
||||
modifications to timestamps in the history file. Fixes issue
|
||||
reported by rens@endoria.net
|
||||
|
||||
9/21
|
||||
----
|
||||
lib/readline/rlconf.h
|
||||
- ENABLE_AUDIT_TTY_SUPPORT: now undefined (off) by default
|
||||
|
||||
9/24
|
||||
----
|
||||
jobs.c
|
||||
- waitchld: if we get a SIGINT while waiting for a child to exit, but the
|
||||
kernel doesn't interrupt the waitpid(2) call, assume the child caught
|
||||
SIGINT if it exited for some reason other than SIGINT. Fix suggested
|
||||
by Stephane Chazelas <stephane.chazelas@gmail.com>
|
||||
|
||||
input.c
|
||||
- make_buffered_stream: use B_TEXT in buffered stream flags instead
|
||||
of (typo) O_TEXT. Report and fix from Eric Blake <eblake@redhat.com>
|
||||
|
||||
9/27
|
||||
----
|
||||
execute_cmd.c
|
||||
- shell_execve: call reset_parser before calling initialize_subshell,
|
||||
which calls delete_all_aliases. reset_parser wants to free the
|
||||
pushed string list, which has pointers back into the alias table
|
||||
(use after free)
|
||||
- execute_simple_command: if we fork for an async command, make sure
|
||||
the child process increments shell_level before performing any
|
||||
word expansions, so $BASH_SUBSHELL is incremented. Fixes issue
|
||||
reported by ziyunfei <446240525@qq.com>
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ extern int evalstring __P((char *, const char *, int));
|
||||
extern void parse_and_execute_cleanup __P((void));
|
||||
extern int parse_string __P((char *, const char *, int, char **));
|
||||
extern int should_suppress_fork __P((COMMAND *));
|
||||
extern int optimize_fork __P((COMMAND *));
|
||||
extern void optimize_fork __P((COMMAND *));
|
||||
|
||||
/* Functions from evalfile.c */
|
||||
extern int maybe_execute_file __P((const char *, int));
|
||||
|
||||
@@ -110,7 +110,7 @@ should_suppress_fork (command)
|
||||
((command->flags & CMD_INVERT_RETURN) == 0));
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
optimize_fork (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
|
||||
@@ -932,6 +932,8 @@ unset_builtin (list)
|
||||
if (tem == -1 && unset_function == 0 && unset_variable == 0)
|
||||
tem = unbind_func (name);
|
||||
|
||||
name = list->word->word; /* reset above for namerefs */
|
||||
|
||||
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
|
||||
was not previously set shall not be considered an error.'' */
|
||||
|
||||
|
||||
+11
-3
@@ -46,6 +46,7 @@ typedef int unix_link_syscall_t __P((const char *, const char *));
|
||||
|
||||
#define LN_SYMLINK 0x01
|
||||
#define LN_UNLINK 0x02
|
||||
#define LN_NOFOLLOW 0x04
|
||||
|
||||
static unix_link_syscall_t *linkfn;
|
||||
static int dolink ();
|
||||
@@ -71,6 +72,10 @@ ln_builtin (list)
|
||||
case 's':
|
||||
flags |= LN_SYMLINK;
|
||||
break;
|
||||
case 'h':
|
||||
case 'n':
|
||||
flags |= LN_NOFOLLOW;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
@@ -139,8 +144,10 @@ mkdirpath (dir, file)
|
||||
|
||||
#if defined (HAVE_LSTAT)
|
||||
# define LSTAT lstat
|
||||
# define LSTAT_OR_STAT_IF(c, f, b) ((c) ? lstat((f), (b)) : stat((f), (b)))
|
||||
#else
|
||||
# define LSTAT stat
|
||||
# define LSTAT_OR_STAT_IF(c, f, b) (stat((f), (b)))
|
||||
#endif
|
||||
|
||||
static int
|
||||
@@ -172,7 +179,7 @@ dolink (src, dst, flags)
|
||||
/* If the destination is a directory, create the final filename by appending
|
||||
the basename of the source to the destination. */
|
||||
dst_path = 0;
|
||||
if ((stat (dst, &dsb) == 0) && S_ISDIR (dsb.st_mode))
|
||||
if ((LSTAT_OR_STAT_IF((flags & LN_NOFOLLOW), dst, &dsb) == 0) && S_ISDIR (dsb.st_mode))
|
||||
{
|
||||
if ((p = strrchr (src, '/')) == 0)
|
||||
p = src;
|
||||
@@ -211,7 +218,8 @@ char *ln_doc[] = {
|
||||
"Create a new directory entry with the same modes as the original",
|
||||
"file. The -f option means to unlink any existing file, permitting",
|
||||
"the link to occur. The -s option means to create a symbolic link.",
|
||||
"By default, ln makes hard links.",
|
||||
"By default, ln makes hard links. Specifying -n or its synonym -h",
|
||||
"causes ln to not resolve symlinks in the target file or directory.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
@@ -222,6 +230,6 @@ struct builtin ln_struct = {
|
||||
ln_builtin, /* function implementing the builtin */
|
||||
BUILTIN_ENABLED, /* initial flags for builtin */
|
||||
ln_doc, /* array of long documentation strings. */
|
||||
"ln [-fs] file1 [file2] OR ln [-fs] file ... directory", /* usage synopsis; becomes short_doc */
|
||||
"ln [-fhns] file1 [file2] OR ln [-fhns] file ... directory", /* usage synopsis; becomes short_doc */
|
||||
0 /* reserved for internal use */
|
||||
};
|
||||
|
||||
+8
-3
@@ -4046,6 +4046,9 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
last_asynchronous_pid = old_last_async_pid;
|
||||
|
||||
CHECK_SIGTERM;
|
||||
|
||||
if (async)
|
||||
subshell_level++; /* not for pipes yet */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4067,6 +4070,8 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
}
|
||||
}
|
||||
|
||||
QUIT; /* XXX */
|
||||
|
||||
/* If we are re-running this as the result of executing the `command'
|
||||
builtin, do not expand the command words a second time. */
|
||||
if ((simple_command->flags & CMD_INHIBIT_EXPANSION) == 0)
|
||||
@@ -4237,7 +4242,8 @@ run_builtin:
|
||||
setup_async_signals ();
|
||||
}
|
||||
|
||||
subshell_level++;
|
||||
if (async == 0)
|
||||
subshell_level++;
|
||||
execute_subshell_builtin_or_function
|
||||
(words, simple_command->redirects, builtin, func,
|
||||
pipe_in, pipe_out, async, fds_to_close,
|
||||
@@ -5464,6 +5470,7 @@ shell_execve (command, args, env)
|
||||
/* We have committed to attempting to execute the contents of this file
|
||||
as shell commands. */
|
||||
|
||||
reset_parser ();
|
||||
initialize_subshell ();
|
||||
|
||||
set_sigint_handler ();
|
||||
@@ -5508,8 +5515,6 @@ shell_execve (command, args, env)
|
||||
clear_fifo_list (); /* pipe fds are what they are now */
|
||||
#endif
|
||||
|
||||
reset_parser ();
|
||||
|
||||
sh_longjmp (subshell_top_level, 1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ make_buffered_stream (fd, buffer, bufsize)
|
||||
if (bufsize == 1)
|
||||
bp->b_flag |= B_UNBUFF;
|
||||
if (O_TEXT && (fcntl (fd, F_GETFL) & O_TEXT) != 0)
|
||||
bp->b_flag |= O_TEXT;
|
||||
bp->b_flag |= B_TEXT;
|
||||
return (bp);
|
||||
}
|
||||
|
||||
|
||||
@@ -3393,6 +3393,13 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
|
||||
if (pid <= 0)
|
||||
continue; /* jumps right to the test */
|
||||
|
||||
/* Linux kernels appear to signal the parent but not interrupt the
|
||||
waitpid() (or restart it even without SA_RESTART) on SIGINT, so if
|
||||
we saw a SIGINT and the process exited or died due to some other
|
||||
signal, assume the child caught the SIGINT. */
|
||||
if (wait_sigint_received && (WIFSIGNALED (status) == 0 || WTERMSIG (status) != SIGINT))
|
||||
child_caught_sigint = 1;
|
||||
|
||||
/* If the child process did die due to SIGINT, forget our assumption
|
||||
that it caught or otherwise handled it. */
|
||||
if (WIFSIGNALED (status) && WTERMSIG (status) == SIGINT)
|
||||
@@ -3624,13 +3631,17 @@ set_job_status_and_cleanup (job)
|
||||
seen it, and wait_sigint_received is non-zero, because keyboard
|
||||
signals are sent to process groups) or via kill(2) to the foreground
|
||||
process by another process (or itself). If the shell did receive the
|
||||
SIGINT, it needs to perform normal SIGINT processing. */
|
||||
SIGINT, it needs to perform normal SIGINT processing. XXX - should
|
||||
this change its behavior depending on whether the last command in an
|
||||
pipeline exited due to SIGINT, or any process in the pipeline? Right
|
||||
now it does this if any process in the pipeline exits due to SIGINT. */
|
||||
else if (wait_sigint_received &&
|
||||
child_caught_sigint == 0 &&
|
||||
IS_FOREGROUND (job) && IS_JOBCONTROL (job) == 0)
|
||||
{
|
||||
int old_frozen;
|
||||
|
||||
itrace("waitchld: special handling for SIGINT");
|
||||
wait_sigint_received = 0;
|
||||
|
||||
/* If SIGINT is trapped, set the exit status so that the trap
|
||||
|
||||
@@ -325,7 +325,7 @@ add_history (string)
|
||||
}
|
||||
}
|
||||
|
||||
temp = alloc_history_entry (string, hist_inittime ());
|
||||
temp = alloc_history_entry ((char *)string, hist_inittime ());
|
||||
|
||||
the_history[history_length] = (HIST_ENTRY *)NULL;
|
||||
the_history[history_length - 1] = temp;
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/* Define this if you want to enable code that talks to the Linux kernel
|
||||
tty auditing system. */
|
||||
#define ENABLE_TTY_AUDIT_SUPPORT
|
||||
/* #define ENABLE_TTY_AUDIT_SUPPORT */
|
||||
|
||||
/* Defaults for the various editing mode indicators, inserted at the beginning
|
||||
of the last (maybe only) line of the prompt if show-mode-in-prompt is on */
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "shell.h"
|
||||
#include "flags.h"
|
||||
#include <y.tab.h> /* use <...> so we pick it up from the build directory */
|
||||
#include "input.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
|
||||
@@ -5873,8 +5873,8 @@ command_substitute (string, quoted)
|
||||
{
|
||||
builtin_ignoring_errexit = 0;
|
||||
change_flag ('e', FLAG_OFF);
|
||||
set_shellopts ();
|
||||
}
|
||||
set_shellopts ();
|
||||
|
||||
/* If we are expanding a redirection, we can dispose of any temporary
|
||||
environment we received, since redirections are not supposed to have
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
+5
-1
@@ -228,5 +228,9 @@ declare -- var="x\001y\177z"$
|
||||
argv[1] = <$'x\001y\177z'>
|
||||
argv[1] = <x^Ay^?z>
|
||||
var=$'x\001y\177z'
|
||||
./exp8.sub: line 16: xyz: syntax error: invalid arithmetic operator (error token is "z")
|
||||
declare -a array=()
|
||||
declare -a array=([0]=$'x\001y\177z')
|
||||
argv[1] = <x^Ay^?z>
|
||||
declare -a array=([0]="x\001y\177z")$
|
||||
declare -a array=([0]=$'x\001y\177z')
|
||||
declare -A array=([$'x\001y\177z']=$'a\242b\002c' )
|
||||
|
||||
+15
-1
@@ -12,6 +12,20 @@ recho ${var@Q}
|
||||
recho ${var@P}
|
||||
echo ${var@A}
|
||||
|
||||
unset array
|
||||
array=( [$'x\001y\177z']=foo ) # should be error
|
||||
echo ${array[@]@A}
|
||||
|
||||
unset array
|
||||
declare -a array=([0]=$'x\001y\177z')
|
||||
declare -p array
|
||||
|
||||
unset array
|
||||
array=( "$var" )
|
||||
recho ${array[@]}
|
||||
echo ${array[@]@A} | sed -n l
|
||||
echo ${array[@]@A}
|
||||
|
||||
unset array
|
||||
declare -A array
|
||||
array=( [$'x\001y\177z']=$'a\242b\002c' )
|
||||
echo ${array[@]@A}
|
||||
|
||||
+1
-2
@@ -24,8 +24,7 @@ f3 ()
|
||||
echo $(echo hi)
|
||||
echo ho
|
||||
echo off to work we go
|
||||
declare -a uu=([0]="" [1]="kghfjk" [2]="jkfzuk" [3]="i
|
||||
")
|
||||
declare -a uu=([0]="" [1]="kghfjk" [2]="jkfzuk" [3]=$'i\n')
|
||||
foo bar
|
||||
foo bar
|
||||
qux:::::bax
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ $'\'abcd\''
|
||||
'
|
||||
1
|
||||
argv[1] = <^?>
|
||||
0000000 del nl
|
||||
0000000 del nl
|
||||
0000002
|
||||
0000000 esc fs gs rs us del nl
|
||||
0000000 esc fs gs rs us del nl
|
||||
0000007
|
||||
\q
|
||||
|
||||
+4
-2
@@ -1,6 +1,8 @@
|
||||
. ./test-glue-functions
|
||||
|
||||
recho $'\c?'
|
||||
|
||||
echo $'\c?' |od -a
|
||||
echo $'\c[\c\\\c]\c^\c_\c?' |od -a
|
||||
echo $'\c?' | od -a | _intl_normalize_spaces
|
||||
echo $'\c[\c\\\c]\c^\c_\c?' | od -a | _intl_normalize_spaces
|
||||
|
||||
echo $'\q'
|
||||
|
||||
@@ -320,7 +320,6 @@ run_pending_traps ()
|
||||
while (pending_traps[sig]--) instead of the if statement. */
|
||||
if (pending_traps[sig])
|
||||
{
|
||||
itrace("run_pending_traps: %d: %d", sig, pending_traps[sig]);
|
||||
if (running_trap == sig+1)
|
||||
/*continue*/;
|
||||
|
||||
@@ -404,7 +403,6 @@ itrace("run_pending_traps: %d: %d", sig, pending_traps[sig]);
|
||||
/* XXX - set pending_traps[sig] = 0 here? */
|
||||
pending_traps[sig] = 0;
|
||||
evalstring (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
|
||||
itrace("run_pending_traps: evalstring returns");
|
||||
#if defined (JOB_CONTROL)
|
||||
restore_pipeline (1);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user