commit bash-20170317 snapshot

This commit is contained in:
Chet Ramey
2017-03-20 16:30:10 -04:00
parent 10729c7b2a
commit f698849a75
16 changed files with 230 additions and 60 deletions
+87
View File
@@ -13362,3 +13362,90 @@ lib/readline/display.c
lib/readline/readline.c
- bind_arrow_keys_internal: add default key bindings for control-
arrow keys, suggested by Per Bothner <per@bothner.com>
3/13
----
doc/{bash.1,bashref.texi}
- clarify the prompt strings the undergo expansion (PS0, PS1, PS2, and
PS4) before being displayed. Based on a report from Grisha Levit
<grishalevit@gmail.com>
3/14
----
input.c
- bufstream_ungetc: return EOF if being asked to unget a character to
a NULL buffer
- buffered_getchar: check buffered_fd is valid and buffers[buffered_fd]
is non-NULL before trying to dereference. Fixes bug reported by
floyd <floyd@floyd.ch>
execute_cmd.c
- execute_null_command: if we fork to execute the command, the subshell
is not interactive
- execute_null_command: for safety's sake, if a redirection attached
to a null command affects fd 0 or the fd the shell is reading for
input, and the redirection can potentially change or close that file
descriptor, force a fork so the redirection is done in a subshell
3/15
----
lib/readline/display.c
- update_line: if we have to output some bytes, and we are outputting
the prompt string, make sure we correct _rl_last_c_pos if we are
at the wrap offset -- what if all of the characters in the prompt
are invisible, so the visible length is 0? Fixes display bug
reported by Grisha Levit <grishalevit@gmail.com>
execute_cmd.c
- undo_partial_redirects: new function, performs redirections specified
in redirection_undo_list and disposes of them. Intended to be used
to unwind redirections performed before a redirection error
- dispose_partial_redirects: new function, disposes of
redirection_undo_list and nulls the list
- execute_command_internal: use undo_partial_redirects
execute_cmd.h
- undo_partial_redirects: extern declaration
- dispose_partial_redirects: extern declaration
subst.c
- exp_jump_to_top_level: if we are throwing an expansion error while
expanding a redirection (expanding_redir != 0), undo any undoable
redirections by calling undo_partial_redirects() so we don't leave
any in place
variables.c
- initialize_shell_variables: if SHELLOPTS is in the environment,
unset the readonly attribute on any existing variable with that
name. It may have been created by processing a -o option on the
command line. Fixes issue reported by Stephane Chazelas
<stephane.chazelas@gmail.com>
3/16
----
lib/readline/histfile.c
- read_history_range: short-circuit and do nothing if the history file
is of 0 size
- read_history_range: make sure the buffer is zero-terminated so the
timestamp tests work right for history files of 1 character. Report
and recommended fix from Denis Martinez <denis.martinez@gmx.com>
lib/readline/complete.c
- compute_lcd_of_matches: when trying to compute the common prefix
of a set of matches while performing case-insensitive completion
matching, don't sort the match list unless rl_sort_completion_matches
is non-zero. Fixes problem reported by Roee Bar <roee@arista.com>
3/18
----
subst.c
- extract_dollar_brace_string: handle process substitution embedded in
a ${...} expansion in the same way as command substitution. Reported
by D630 <d630@posteo.net>
parse.y
- LEX_GTLT: new flag, set by parse_matched_pair when a `<' or '>' is
read
- parse_matched_pair: handle an embedded process substitution like an
embedded command substitution if we are parsing an array index or
a dollar-brace expansion. Reported by D630 <d630@posteo.net>
+1
View File
@@ -3465,6 +3465,7 @@ history_completion_generator (hint_text, state)
while (history_completion_array && history_completion_array[local_index])
{
/* XXX - should this use completion-ignore-case? */
if (strncmp (text, history_completion_array[local_index++], len) == 0)
return (savestring (history_completion_array[local_index - 1]));
}
+10 -2
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Sat Mar 4 13:06:51 EST 2017
.\" Last Change: Mon Mar 13 12:04:35 EDT 2017
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2017 March 4" "GNU Bash 4.4"
.TH BASH 1 "2017 March 13" "GNU Bash 4.4"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -2436,6 +2436,7 @@ The value of this parameter is expanded as with
and the value is printed before each command
.B bash
displays during an execution trace. The first character of
the expanded value of
.SM
.B PS4
is replicated multiple times, as necessary, to indicate multiple
@@ -5120,9 +5121,16 @@ when it is ready to read a command, and the secondary prompt
when it needs more input to complete a command.
.B Bash
displays
.SM
.B PS0
after it reads a command but before executing it.
.B Bash
displays
.SM
.B PS4
as described above
before tracing each command when the \fB\-x\fP option is enabled.
.B Bash
allows these prompt strings to be customized by inserting a number of
backslash-escaped special characters that are decoded as follows:
.RS
+14 -7
View File
@@ -5458,6 +5458,8 @@ sequences that are expanded before @env{PS1} is displayed.
@item PS2
The secondary prompt string. The default value is @samp{> }.
@env{PS2} is expanded in the same way as @env{PS1} before being
displayed.
@end vtable
@@ -6079,10 +6081,11 @@ The value of this variable is used as the prompt for the
@code{select} command prompts with @samp{#? }
@item PS4
The value is the prompt printed before the command line is echoed
when the @option{-x} option is set (@pxref{The Set Builtin}).
The first character of @env{PS4} is replicated multiple times, as
necessary, to indicate multiple levels of indirection.
The value of this parameter is expanded like @var{PS1}
and the expanded value is the prompt printed before the command line
is echoed when the @option{-x} option is set (@pxref{The Set Builtin}).
The first character of the expanded value is replicated multiple times,
as necessary, to indicate multiple levels of indirection.
The default is @samp{+ }.
@item PWD
@@ -6571,7 +6574,10 @@ signals @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
Bash expands and displays @env{PS1} before reading the first line
of a command, and expands and displays @env{PS2} before reading the
second and subsequent lines of a multi-line command.
Bash displays @env{PS0} after it reads a command but before executing it.
Bash expands and displays @env{PS0} after it reads a command but before
executing it.
See @ref{Controlling the Prompt}, for a complete list of prompt
string escape sequences.
@item
Bash executes the value of the @env{PROMPT_COMMAND} variable as a command
@@ -7233,7 +7239,8 @@ has a non-null value, then the
value is executed just as if it had been typed on the command line.
In addition, the following table describes the special characters which
can appear in the prompt variables @env{PS1} to @env{PS4}:
can appear in the prompt variables @env{PS0}, @env{PS1}, @env{PS2}, and
@env{PS4}:
@table @code
@item \a
@@ -8434,7 +8441,7 @@ If Readline is not enabled, this option has no effect.
@item --enable-prompt-string-decoding
Turn on the interpretation of a number of backslash-escaped characters
in the @env{$PS1}, @env{$PS2}, @env{$PS3}, and @env{$PS4} prompt
in the @env{$PS0}, @env{$PS1}, @env{$PS2}, and @env{$PS4} prompt
strings. See @ref{Controlling the Prompt}, for a complete list of prompt
string escape sequences.
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2017 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sat Mar 4 13:06:24 EST 2017
@set LASTCHANGE Mon Mar 13 11:48:21 EDT 2017
@set EDITION 4.4
@set VERSION 4.4
@set UPDATED 4 March 2017
@set UPDATED 13 March 2017
@set UPDATED-MONTH March 2017
+33 -18
View File
@@ -449,6 +449,16 @@ cleanup_redirects (list)
dispose_redirects (list);
}
void
undo_partial_redirects ()
{
if (redirection_undo_list)
{
cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
}
}
#if 0
/* Function to unwind_protect the redirections for functions and builtins. */
static void
@@ -469,6 +479,16 @@ dispose_exec_redirects ()
}
}
void
dispose_partial_redirects ()
{
if (redirection_undo_list)
{
dispose_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
}
}
#if defined (JOB_CONTROL)
/* A function to restore the signal mask to its proper value when the shell
is interrupted or errors occur while creating a pipeline. */
@@ -728,8 +748,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
redirection.) */
if (do_redirections (command->redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
{
cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
undo_partial_redirects ();
dispose_exec_redirects ();
#if defined (PROCESS_SUBSTITUTION)
if (saved_fifo)
@@ -742,8 +761,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
{
/* XXX - why copy here? */
my_undo_list = (REDIRECT *)copy_redirects (redirection_undo_list);
dispose_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
dispose_partial_redirects ();
}
else
my_undo_list = (REDIRECT *)NULL;
@@ -752,8 +770,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
{
/* XXX - why copy here? */
exec_undo_list = (REDIRECT *)copy_redirects (exec_redirection_undo_list);
dispose_redirects (exec_redirection_undo_list);
exec_redirection_undo_list = (REDIRECT *)NULL;
dispose_exec_redirects ();
}
else
exec_undo_list = (REDIRECT *)NULL;
@@ -1034,10 +1051,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
}
if (my_undo_list)
{
do_redirections (my_undo_list, RX_ACTIVE);
dispose_redirects (my_undo_list);
}
cleanup_redirects (my_undo_list);
if (exec_undo_list)
dispose_redirects (exec_undo_list);
@@ -3873,7 +3887,11 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
REDIRECT *rd;
for (forcefork = 0, rd = redirects; rd; rd = rd->next)
forcefork += rd->rflags & REDIR_VARASSIGN;
{
forcefork += rd->rflags & REDIR_VARASSIGN;
/* Safety */
forcefork += (rd->redirector.dest == 0 || fd_is_bash_input (rd->redirector.dest)) && (INPUT_REDIRECT (rd->instruction) || TRANSLATE_REDIRECT (rd->instruction) || rd->instruction == r_close_this);
}
if (forcefork || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
{
@@ -3890,6 +3908,8 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
coproc_closeall ();
#endif
interactive = 0; /* XXX */
subshell_environment = 0;
if (async)
subshell_environment |= SUBSHELL_ASYNC;
@@ -5041,8 +5061,7 @@ execute_builtin_or_function (words, builtin, var, redirects,
if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
{
cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
undo_partial_redirects ();
dispose_exec_redirects ();
#if defined (PROCESS_SUBSTITUTION)
free (ofifo_list);
@@ -5109,11 +5128,7 @@ execute_builtin_or_function (words, builtin, var, redirects,
discard_unwind_frame ("saved-redirects");
}
if (redirection_undo_list)
{
cleanup_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
}
undo_partial_redirects ();
#if defined (PROCESS_SUBSTITUTION)
/* Close any FIFOs created by this builtin or function. */
+4 -1
View File
@@ -68,7 +68,10 @@ extern int execute_command __P((COMMAND *));
extern int execute_command_internal __P((COMMAND *, int, int, int, struct fd_bitmap *));
extern int shell_execve __P((char *, char **, char **));
extern void setup_async_signals __P((void));
extern void dispose_exec_redirects __P ((void));
extern void undo_partial_redirects __P((void));
extern void dispose_partial_redirects __P((void));
extern void dispose_exec_redirects __P((void));
extern int execute_shell_function __P((SHELL_VAR *, WORD_LIST *));
+10
View File
@@ -36,6 +36,16 @@
# endif
#endif
/* New definition to use, moving away from __P since it's part of a reserved
namespace */
#if !defined (PARAMS)
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES)
# define PARAMS(protos) protos
# else
# define PARAMS(protos) ()
# endif
#endif
/* Fortify, at least, has trouble with this definition */
#if defined (HAVE_STRINGIZE)
# define CPP_STRING(x) #x
+4 -1
View File
@@ -525,7 +525,7 @@ bufstream_ungetc(c, bp)
int c;
BUFFERED_STREAM *bp;
{
if (c == EOF || bp->b_inputp == 0)
if (c == EOF || bp == 0 || bp->b_inputp == 0)
return (EOF);
bp->b_buffer[--bp->b_inputp] = c;
@@ -556,6 +556,9 @@ buffered_getchar ()
{
CHECK_TERMSIG;
if (bash_input.location.buffered_fd < 0 || buffers[bash_input.location.buffered_fd] == 0)
return EOF;
#if !defined (DJGPP)
return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
#else
+4 -3
View File
@@ -1422,7 +1422,8 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
}
/* sort the list to get consistent answers. */
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
if (rl_sort_completion_matches)
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
si = strlen (text);
lx = (si <= low) ? si : low; /* check shorter of text and matches */
@@ -2644,7 +2645,7 @@ rl_filename_completion_function (const char *text, int state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
int
rl_old_menu_complete (int count, invoking_key)
rl_old_menu_complete (int count, int invoking_key)
{
rl_compentry_func_t *our_func;
int matching_filenames, found_quote;
@@ -2947,7 +2948,7 @@ rl_menu_complete (int count, int ignore)
}
int
rl_backward_menu_complete (int count, key)
rl_backward_menu_complete (int count, int key)
{
/* Positive arguments to backward-menu-complete translate into negative
arguments for menu-complete, and vice versa. */
+1 -1
View File
@@ -2075,7 +2075,7 @@ dumb_update:
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
if (current_line == 0 && wrap_offset &&
displaying_prompt_first_line &&
_rl_last_c_pos > wrap_offset &&
_rl_last_c_pos >= wrap_offset && /* XXX was > */
((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
+4
View File
@@ -292,6 +292,9 @@ read_history_range (const char *filename, int from, int to)
goto error_and_exit;
}
if (file_size == 0)
return 0; /* don't waste time if we don't have to */
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
@@ -338,6 +341,7 @@ read_history_range (const char *filename, int from, int to)
/* Start at beginning of file, work to end. */
bufend = buffer + chars_read;
*bufend = '\0'; /* null-terminate buffer for timestamp checks */
current_line = 0;
/* Heuristic: the history comment character rarely changes, so assume we
+4
View File
@@ -1300,6 +1300,10 @@ bind_arrow_keys_internal (Keymap map)
rl_bind_keyseq_if_unbound ("\033[1;5D", rl_backward_word);
rl_bind_keyseq_if_unbound ("\033[3;5~", rl_kill_word);
/* Key bindings for alt-arrow keys */
rl_bind_keyseq_if_unbound ("\033[1;3C", rl_forward_word);
rl_bind_keyseq_if_unbound ("\033[1;3D", rl_backward_word);
#if defined (__MINGW32__)
rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history);
+29 -22
View File
@@ -1,6 +1,6 @@
/* parse.y - Yacc grammar for bash. */
/* Copyright (C) 1989-2015 Free Software Foundation, Inc.
/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -116,15 +116,7 @@ typedef void *alias_t;
extern int extended_glob;
#endif
extern int eof_encountered;
extern int no_line_editing, running_under_emacs;
extern int current_command_number;
extern int sourcelevel, parse_and_execute_level;
extern pid_t last_command_subst_pid;
extern char *dist_version;
extern int patch_level;
extern int dump_translatable_strings, dump_po_strings;
extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
#if !defined (errno)
extern int errno;
@@ -3335,18 +3327,19 @@ tokword:
#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
/* Lexical state while parsing a grouping construct or $(...). */
#define LEX_WASDOL 0x001
#define LEX_CKCOMMENT 0x002
#define LEX_INCOMMENT 0x004
#define LEX_PASSNEXT 0x008
#define LEX_RESWDOK 0x010
#define LEX_CKCASE 0x020
#define LEX_INCASE 0x040
#define LEX_INHEREDOC 0x080
#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
#define LEX_QUOTEDDOC 0x400 /* here doc with quoted delim */
#define LEX_INWORD 0x800
#define LEX_WASDOL 0x0001
#define LEX_CKCOMMENT 0x0002
#define LEX_INCOMMENT 0x0004
#define LEX_PASSNEXT 0x0008
#define LEX_RESWDOK 0x0010
#define LEX_CKCASE 0x0020
#define LEX_INCASE 0x0040
#define LEX_INHEREDOC 0x0080
#define LEX_HEREDELIM 0x0100 /* reading here-doc delimiter */
#define LEX_STRIPDOC 0x0200 /* <<- strip tabs from here doc delim */
#define LEX_QUOTEDDOC 0x0400 /* here doc with quoted delim */
#define LEX_INWORD 0x0800
#define LEX_GTLT 0x1000
#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
@@ -3377,7 +3370,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
int open, close;
int *lenp, flags;
{
int count, ch, tflags;
int count, ch, prevch, tflags;
int nestlen, ttranslen, start_lineno;
char *ret, *nestret, *ttrans;
int retind, retsize, rflags;
@@ -3399,8 +3392,10 @@ parse_matched_pair (qc, open, close, lenp, flags)
retind = 0;
start_lineno = line_number;
ch = EOF; /* just in case */
while (count)
{
prevch = ch;
ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
if (ch == EOF)
@@ -3594,6 +3589,12 @@ parse_matched_pair (qc, open, close, lenp, flags)
}
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
goto parse_dollar_word;
#if defined (PROCESS_SUBSTITUTION)
/* XXX - technically this should only be recognized at the start of
a word */
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_GTLT) && (ch == '(')) /* ) */
goto parse_dollar_word;
#endif
}
/* Parse an old-style command substitution within double quotes as a
single word. */
@@ -3625,6 +3626,12 @@ parse_dollar_word:
FREE (nestret);
}
#if defined (PROCESS_SUBSTITUTION)
if MBTEST((ch == '<' || ch == '>') && (tflags & LEX_GTLT) == 0)
tflags |= LEX_GTLT;
else
tflags &= ~LEX_GTLT;
#endif
if MBTEST(ch == '$' && (tflags & LEX_WASDOL) == 0)
tflags |= LEX_WASDOL;
else
+16
View File
@@ -1563,6 +1563,20 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
continue;
}
#if defined (PROCESS_SUBSTITUTION)
/* Technically this should only work at the start of a word */
if ((string[i] == '<' || string[i] == '>') && string[i+1] == LPAREN)
{
si = i + 2;
t = extract_process_subst (string, (string[i] == '<' ? "<(" : ">)"), &si, flags|SX_NOALLOC);
CHECK_STRING_OVERRUN (i, si, slen, c);
i = si + 1;
continue;
}
#endif
/* Pass the contents of double-quoted strings through verbatim. */
if (c == '"')
{
@@ -10281,6 +10295,8 @@ exp_jump_to_top_level (v)
/* Cleanup code goes here. */
expand_no_split_dollar_star = 0; /* XXX */
if (expanding_redir)
undo_partial_redirects ();
expanding_redir = 0;
assigning_in_environment = 0;
+7 -3
View File
@@ -412,7 +412,10 @@ initialize_shell_variables (env, privmode)
#endif
{
ro = 0;
if (posixly_correct && STREQ (name, "SHELLOPTS"))
/* If we processed a command-line option that caused SHELLOPTS to be
set, it may already be set (and read-only) by the time we process
the shell's environment. */
if (/* posixly_correct &&*/ STREQ (name, "SHELLOPTS"))
{
temp_var = find_variable ("SHELLOPTS");
ro = temp_var && readonly_p (temp_var);
@@ -585,8 +588,9 @@ initialize_shell_variables (env, privmode)
#endif /* HISTORY */
#if defined (READLINE) && defined (STRICT_POSIX)
/* POSIXLY_CORRECT will only be 1 here if the shell was compiled
-DSTRICT_POSIX */
/* POSIXLY_CORRECT will be 1 here if the shell was compiled
-DSTRICT_POSIX or if POSIXLY_CORRECT was supplied in the shell's
environment */
if (interactive_shell && posixly_correct && no_line_editing == 0)
rl_prefer_env_winsize = 1;
#endif /* READLINE && STRICT_POSIX */