commit bash-20161104 snapshot

This commit is contained in:
Chet Ramey
2016-11-05 13:28:27 -04:00
parent 553a7d66e4
commit ec1101c37e
13 changed files with 201 additions and 12 deletions
+60 -1
View File
@@ -12105,7 +12105,7 @@ examples/loadables/rm.c
<tim.ruehsen@gmx.de>, heavily rewritten for inclusion as loadable
examples/loadables/Makefile.in
- rm: add rules to build rm as one of the standard targets
- rm: add rules to build rm as one of the `other' targets
examples/loadables/stat.c
- stat: new loadable builtin that takes a filename and loads the info
@@ -12140,3 +12140,62 @@ subst.c
- process_substitute: call discard_last_procsub_child instead of
calling discard_pipeline directly. Fixes bug reported by
Christian Weisgerber <naddy@mips.inka.de>
11/3
----
shell.h
- EX_DISKFALLBACK: new special return status available to builtins;
means to attempt to execute a disk command with the same name as
the builtin
examples/loadables/rm.c
- if we see the -i option, return EX_DISKFALLBACK
execute_cmd.c
- execute_simple_command: if executing a builtin returns EX_DISKFALLBACK,
try running execute_disk_command instead
bashline.c
- shell_expand_line: use expand_word to expand the readline line
buffer, which allows us to pass flags with the word. If a numeric
argument is supplied, do not perform quote removal (pass
Q_HERE_DOCUMENT since here-doc quoting does the right thing) and
do not perform command or process subsitution. From a suggestion
by Dabrien 'Dabe' Murphy <dabe@dabe.com> based on an old bug-bash
discussion
subst.c
- expand_word_internal: note that we have added a quoted IFS char to
istring by setting sentinel has_quoted_ifs. Usually we only add
one if we are not going to be performing word splitting, but we
will not perform word splitting if there's no expansion, so we need
to take care of that case
- expand_word_internal: when performing final word split, if there are
no expansions but has_quoted_ifs is non-zero, call remove_quoted_ifs()
to remove any quoted ifs characters we added while processing
- remove_quoted_ifs: new function, removes CTLESC chars preceding
(single-byte) chars in IFS. Used when we are not performing word
splitting. Fixes bug reported by Martijn Dekker <martijn@inlv.org>
11/4
----
lib/readline/macro.c
- _rl_peek_macro_key: return the next character from the current
keyboard macro; the next character from the `next' keyboard macro,
if there is one, if at the end of the current macro; or 0 to
indicate that we are at the end of a keyboard macro sequence
lib/readline/rlprivate.h
- _rl_peek_macro_key: extern declaration
lib/readline/readline.c
- _rl_dispatch_subseq: add test for ESC at the end of a keyboard macro,
which should cause the keyboard timeout for ESC to kick in. The
previous test didn't run the timeout code if executing from a macro,
even if we had read the last character of the macro. Fixes bug
reported by Clark Wang <clarkw@vmware.com>
lib/glob/sm_loop.c
- GMATCH: allow trailing backslash in pattern to explicitly match a
backslash that is the last character in the string. Bug report from
Stephane Chazelas <stephane.chazelas@gmail.com>
+11
View File
@@ -2704,6 +2704,7 @@ shell_expand_line (count, ignore)
{
char *new_line;
WORD_LIST *expanded_string;
WORD_DESC *w;
new_line = 0;
#if defined (BANG_HISTORY)
@@ -2733,9 +2734,19 @@ shell_expand_line (count, ignore)
/* If there is variable expansion to perform, do that as a separate
operation to be undone. */
#if 1
w = alloc_word_desc ();
w->word = savestring (rl_line_buffer);
w->flags = rl_explicit_arg ? (W_NOPROCSUB|W_NOCOMSUB) : 0;
expanded_string = expand_word (w, rl_explicit_arg ? Q_HERE_DOCUMENT : 0);
dispose_word (w);
#else
new_line = savestring (rl_line_buffer);
expanded_string = expand_string (new_line, 0);
FREE (new_line);
#endif
if (expanded_string == 0)
{
new_line = (char *)xmalloc (1);
+3 -1
View File
@@ -122,7 +122,7 @@ rm_builtin (list)
rval = EXECUTION_SUCCESS;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "Rrf")) != -1)
while ((opt = internal_getopt (list, "Rrfi")) != -1)
{
switch (opt)
{
@@ -133,6 +133,8 @@ rm_builtin (list)
case 'f':
force = 1;
break;
case 'i':
return (EX_DISKFALLBACK);
CASE_HELPOPT;
default:
builtin_usage ();
+24 -1
View File
@@ -4096,13 +4096,15 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
if (dofork)
{
char *p;
/* Do this now, because execute_disk_command will do it anyway in the
vast majority of cases. */
maybe_make_export_env ();
/* Don't let a DEBUG trap overwrite the command string to be saved with
the process/job associated with this child. */
if (make_child (savestring (the_printed_command_except_trap), async) == 0)
if (make_child (p = savestring (the_printed_command_except_trap), async) == 0)
{
already_forked = 1;
simple_command->flags |= CMD_NO_FORK;
@@ -4135,6 +4137,8 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
if (async)
subshell_level++; /* not for pipes yet */
FREE (p);
}
else
{
@@ -4356,6 +4360,15 @@ run_builtin:
last_command_exit_value = EXECUTION_FAILURE;
jump_to_top_level (ERREXIT);
}
break;
case EX_DISKFALLBACK:
/* XXX - experimental */
itrace("execute_simple_command: fallback to file system");
executing_builtin = old_builtin;
executing_command_builtin = old_command_builtin;
builtin = 0;
/* XXX - redirections will have to be performed again */
goto execute_from_filesystem;
}
result = builtin_status (result);
if (builtin_is_special)
@@ -4390,6 +4403,7 @@ run_builtin:
goto run_builtin;
}
execute_from_filesystem:
if (command_line == 0)
command_line = savestring (the_printed_command_except_trap ? the_printed_command_except_trap : "");
@@ -4958,6 +4972,15 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
fflush (stdout);
if (r == EX_USAGE)
r = EX_BADUSAGE;
/* XXX - experimental */
else if (r == EX_DISKFALLBACK)
{
char *command_line;
itrace("execute_subshell_builtin_or_function: fall back to disk command");
command_line = savestring (the_printed_command_except_trap ? the_printed_command_except_trap : "");
r = execute_disk_command (words, (REDIRECT *)0, command_line,
-1, -1, async, (struct fd_bitmap *)0, flags|CMD_NO_FORK);
}
sh_exit (r);
}
}
+3
View File
@@ -1961,6 +1961,9 @@ make_child (command, async_p)
signals to the default state for a new process. */
pid_t mypid;
/* If this ends up being changed to modify or use `command' in the
child process, go back and change callers who free `command' in
the child process when this returns. */
mypid = getpid ();
#if defined (BUFFERED_INPUT)
/* Close default_buffered_input if it's > 0. We don't close it if it's
+3
View File
@@ -103,6 +103,9 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
break;
case L('\\'): /* backslash escape removes special meaning */
if (p == pe && sc == '\\' && (n+1 == se))
break;
if (p == pe)
return FNM_NOMATCH;
+5 -1
View File
@@ -81,7 +81,7 @@
#else
# include <strings.h>
#endif
#include <errno.h>
#include <stdio.h>
/* Define getpagesize () if the system does not. */
@@ -246,6 +246,10 @@ static const unsigned long binsizes[NBUCKETS] = {
/* binsizes[x] == (1 << ((x) + 3)) */
#define binsize(x) binsizes[(x)]
#if !defined (errno)
extern int errno;
#endif
/* Declarations for internal functions */
static PTR_T internal_malloc __P((size_t, const char *, int, int));
static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
+18 -1
View File
@@ -100,7 +100,10 @@ _rl_with_macro_input (string)
return;
}
_rl_push_executing_macro ();
#if 0
if (rl_executing_macro) /* XXX - later */
#endif
_rl_push_executing_macro ();
rl_executing_macro = string;
executing_macro_index = 0;
RL_SETSTATE(RL_STATE_MACROINPUT);
@@ -128,10 +131,24 @@ _rl_next_macro_key ()
_rl_pop_executing_macro ();
return c;
#else
/* XXX - consider doing the same as the callback code, just not testing
whether we're running in callback mode */
return (rl_executing_macro[executing_macro_index++]);
#endif
}
int
_rl_peek_macro_key ()
{
if (rl_executing_macro == 0)
return (0);
if (rl_executing_macro[executing_macro_index] == 0 && (macro_list == 0 || macro_list->string == 0))
return (0);
if (rl_executing_macro[executing_macro_index] == 0 && macro_list && macro_list->string)
return (macro_list->string[0]);
return (rl_executing_macro[executing_macro_index]);
}
int
_rl_prev_macro_key ()
{
+9
View File
@@ -920,6 +920,15 @@ _rl_dispatch_subseq (key, map, got_subseq)
_rl_pushed_input_available () == 0 &&
_rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0)
return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
/* This is a very specific test. It can possibly be generalized in
the future, but for now it handles a specific case of ESC being
the last character in a keyboard macro. */
if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap &&
(RL_ISSTATE (RL_STATE_INPUTPENDING) == 0) &&
(RL_ISSTATE (RL_STATE_MACROINPUT) && _rl_peek_macro_key () == 0) &&
_rl_pushed_input_available () == 0 &&
_rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0)
return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
#endif
RESIZE_KEYSEQ_BUFFER ();
+1
View File
@@ -413,6 +413,7 @@ extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_tty_set_echoing PARAMS((int));
extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
+1
View File
@@ -309,6 +309,7 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_peek_macro_key PARAMS((void));
extern int _rl_next_macro_key PARAMS((void));
extern int _rl_prev_macro_key PARAMS((void));
extern void _rl_push_executing_macro PARAMS((void));
+1
View File
@@ -72,6 +72,7 @@ extern int EOF_Reached;
#define EX_REDIRFAIL 259 /* redirection failed */
#define EX_BADASSIGN 260 /* variable assignment error */
#define EX_EXPFAIL 261 /* word expansion failed */
#define EX_DISKFALLBACK 262 /* fall back to disk command from builtin */
/* Flag values that control parameter pattern substitution. */
#define MATCH_ANY 0x000
+62 -7
View File
@@ -4149,11 +4149,43 @@ remove_quoted_escapes (string)
return (string);
}
/* Perform quoted null character removal on STRING. We don't allow any
quoted null characters in the middle or at the ends of strings because
of how expand_word_internal works. remove_quoted_nulls () turns
STRING into an empty string iff it only consists of a quoted null,
and removes all unquoted CTLNUL characters. */
/* Remove quoted $IFS characters from STRING. Quoted IFS characters are
added to protect them from word splitting, but we need to remove them
if no word splitting takes place. This returns newly-allocated memory,
so callers can use it to replace savestring(). */
char *
remove_quoted_ifs (string)
char *string;
{
register size_t slen;
register int i, j, prev_i;
char *ret, *send;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
i = j = 0;
ret = (char *)xmalloc (slen + 1);
while (i < slen)
{
if (string[i] == CTLESC)
{
i++;
if (string[i] == 0 || isifs (string[i]) == 0)
ret[j++] = CTLESC;
if (i == slen)
break;
}
COPY_CHAR_I (ret, j, string, send, i);
}
ret[j] = '\0';
return (ret);
}
char *
remove_quoted_nulls (string)
char *string;
@@ -9084,8 +9116,10 @@ expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_somethin
/* State flags */
int had_quoted_null;
int has_quoted_ifs; /* did we add a quoted $IFS character here? */
int has_dollar_at, temp_has_dollar_at;
int split_on_spaces;
int local_expanded;
int tflag;
int pflags; /* flags passed to param_expand */
int mb_cur_max;
@@ -9119,6 +9153,7 @@ expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_somethin
istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
istring[istring_index = 0] = '\0';
quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
has_quoted_ifs = 0;
split_on_spaces = 0;
quoted_state = UNQUOTED;
@@ -9247,7 +9282,10 @@ add_string:
word->flags |= W_ASSIGNRHS; /* affects $@ */
if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
goto add_ifs_character;
{
has_quoted_ifs++;
goto add_ifs_character;
}
else
goto add_character;
@@ -9320,6 +9358,7 @@ add_string:
case '$':
if (expanded_something)
*expanded_something = 1;
local_expanded = 1;
temp_has_dollar_at = 0;
pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
@@ -9386,6 +9425,7 @@ add_string:
if (expanded_something)
*expanded_something = 1;
local_expanded = 1;
if (word->flags & W_NOCOMSUB)
/* sindex + 1 because string[sindex] == '`' */
@@ -9536,6 +9576,7 @@ add_twochars:
*contains_dollar_at = 1;
if (expanded_something)
*expanded_something = 1;
local_expanded = 1;
}
}
else
@@ -9663,6 +9704,8 @@ add_twochars:
add_ifs_character:
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0))
{
if ((quoted&(Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)
has_quoted_ifs++;
if (string[sindex]) /* from old goto dollar_add_string */
sindex++;
if (c == 0)
@@ -9840,7 +9883,19 @@ finished_with_string:
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
else
{
tword = make_bare_word (istring);
#if 0
/* XXX might want to use *expanded_something == 0 instead of
local_expanded here */
if (local_expanded == 0 && has_quoted_ifs)
#else
if (expanded_something && *expanded_something == 0 && has_quoted_ifs)
#endif
{
tword = alloc_word_desc ();
tword->word = remove_quoted_ifs (istring);
}
else
tword = make_bare_word (istring);
set_word_flags:
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
tword->flags |= W_QUOTED;