mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-08 19:22:39 +02:00
bash-5.2-alpha release
This commit is contained in:
+258
-72
@@ -1,6 +1,6 @@
|
||||
/* bashline.c -- Bash's interface to the readline library. */
|
||||
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "shmbutil.h"
|
||||
#include "trap.h"
|
||||
#include "flags.h"
|
||||
#include "timer.h"
|
||||
|
||||
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
|
||||
# include <mbstr.h> /* mbschr */
|
||||
@@ -141,6 +142,8 @@ static int bash_kill_shellword PARAMS((int, int));
|
||||
static int bash_backward_kill_shellword PARAMS((int, int));
|
||||
static int bash_transpose_shellwords PARAMS((int, int));
|
||||
|
||||
static int bash_spell_correct_shellword PARAMS((int, int));
|
||||
|
||||
/* Helper functions for Readline. */
|
||||
static char *restore_tilde PARAMS((char *, char *));
|
||||
static char *maybe_restore_tilde PARAMS((char *, char *));
|
||||
@@ -189,6 +192,8 @@ static int return_zero PARAMS((const char *));
|
||||
|
||||
static char *bash_dequote_filename PARAMS((char *, int));
|
||||
static char *quote_word_break_chars PARAMS((char *));
|
||||
static int bash_check_expchar PARAMS((char *, int, int *, int *));
|
||||
static void set_filename_quote_chars PARAMS((int, int, int));
|
||||
static void set_filename_bstab PARAMS((const char *));
|
||||
static char *bash_quote_filename PARAMS((char *, int, char *));
|
||||
|
||||
@@ -225,6 +230,7 @@ static char **prog_complete_matches;
|
||||
|
||||
extern int no_symbolic_links;
|
||||
extern STRING_INT_ALIST word_token_alist[];
|
||||
extern sh_timer *read_timeout;
|
||||
|
||||
/* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual
|
||||
completion functions which indicate what type of completion should be
|
||||
@@ -370,7 +376,8 @@ enable_hostname_completion (on_or_off)
|
||||
int on_or_off;
|
||||
{
|
||||
int old_value;
|
||||
char *at, *nv, *nval;
|
||||
char *nv, *nval;
|
||||
const char *at;
|
||||
|
||||
old_value = perform_hostname_completion;
|
||||
|
||||
@@ -430,7 +437,7 @@ enable_hostname_completion (on_or_off)
|
||||
strcpy (nval + 1, rl_completer_word_break_characters);
|
||||
}
|
||||
|
||||
free (rl_completer_word_break_characters);
|
||||
free ((void *)rl_completer_word_break_characters);
|
||||
rl_completer_word_break_characters = nval;
|
||||
}
|
||||
|
||||
@@ -468,6 +475,9 @@ initialize_readline ()
|
||||
rl_add_defun ("shell-backward-kill-word", bash_backward_kill_shellword, -1);
|
||||
rl_add_defun ("shell-transpose-words", bash_transpose_shellwords, -1);
|
||||
|
||||
rl_add_defun ("spell-correct-word", bash_spell_correct_shellword, -1);
|
||||
rl_bind_key_if_unbound_in_map ('s', bash_spell_correct_shellword, emacs_ctlx_keymap);
|
||||
|
||||
#ifdef ALIAS
|
||||
rl_add_defun ("alias-expand-line", alias_expand_line, -1);
|
||||
# ifdef BANG_HISTORY
|
||||
@@ -666,6 +676,8 @@ bashline_reset ()
|
||||
rl_attempted_completion_function = attempt_shell_completion;
|
||||
rl_completion_entry_function = NULL;
|
||||
rl_ignore_some_completions_function = filename_completion_ignore;
|
||||
|
||||
complete_fullquote = 1;
|
||||
rl_filename_quote_characters = default_filename_quote_characters;
|
||||
set_filename_bstab (rl_filename_quote_characters);
|
||||
|
||||
@@ -1028,6 +1040,8 @@ posix_edit_macros (count, key)
|
||||
char alias_name[3], *alias_value, *macro;
|
||||
|
||||
c = rl_read_key ();
|
||||
if (c <= 0)
|
||||
return 0;
|
||||
alias_name[0] = '_';
|
||||
alias_name[1] = c;
|
||||
alias_name[2] = '\0';
|
||||
@@ -1320,6 +1334,55 @@ bash_transpose_shellwords (count, key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Directory name spelling correction on the current word (not shellword).
|
||||
COUNT > 1 is not exactly correct yet. */
|
||||
static int
|
||||
bash_spell_correct_shellword (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int opoint, wbeg, wend;
|
||||
char *text, *newdir;
|
||||
|
||||
opoint = rl_point;
|
||||
while (count)
|
||||
{
|
||||
bash_backward_shellword (1, key);
|
||||
wbeg = rl_point;
|
||||
bash_forward_shellword (1, key);
|
||||
wend = rl_point;
|
||||
|
||||
if (wbeg > wend)
|
||||
break;
|
||||
|
||||
text = rl_copy_text (wbeg, wend);
|
||||
|
||||
newdir = dirspell (text);
|
||||
if (newdir)
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
rl_delete_text (wbeg, wend);
|
||||
rl_point = wbeg;
|
||||
if (*newdir)
|
||||
rl_insert_text (newdir);
|
||||
rl_mark = wbeg;
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
|
||||
free (text);
|
||||
free (newdir);
|
||||
|
||||
if (rl_point >= rl_end)
|
||||
break;
|
||||
|
||||
count--;
|
||||
|
||||
if (count)
|
||||
bash_forward_shellword (1, key); /* XXX */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* How To Do Shell Completion */
|
||||
@@ -1516,6 +1579,7 @@ attempt_shell_completion (text, start, end)
|
||||
matches = (char **)NULL;
|
||||
rl_ignore_some_completions_function = filename_completion_ignore;
|
||||
|
||||
complete_fullquote = 1; /* full filename quoting by default */
|
||||
rl_filename_quote_characters = default_filename_quote_characters;
|
||||
set_filename_bstab (rl_filename_quote_characters);
|
||||
set_directory_hook ();
|
||||
@@ -1560,7 +1624,7 @@ attempt_shell_completion (text, start, end)
|
||||
in_command_position++;
|
||||
|
||||
if (check_redir (ti) == 1)
|
||||
in_command_position = 0;
|
||||
in_command_position = -1; /* sentinel that we're not the first word on the line */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1569,7 +1633,7 @@ attempt_shell_completion (text, start, end)
|
||||
assignments. */
|
||||
}
|
||||
|
||||
if (in_command_position && invalid_completion (text, ti))
|
||||
if (in_command_position > 0 && invalid_completion (text, ti))
|
||||
{
|
||||
rl_attempted_completion_over = 1;
|
||||
return ((char **)NULL);
|
||||
@@ -1577,9 +1641,9 @@ attempt_shell_completion (text, start, end)
|
||||
|
||||
/* Check that we haven't incorrectly flagged a closed command substitution
|
||||
as indicating we're in a command position. */
|
||||
if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' &&
|
||||
if (in_command_position > 0 && ti >= 0 && rl_line_buffer[ti] == '`' &&
|
||||
*text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0)
|
||||
in_command_position = 0;
|
||||
in_command_position = -1; /* not following a command separator */
|
||||
|
||||
/* Special handling for command substitution. If *TEXT is a backquote,
|
||||
it can be the start or end of an old-style command substitution, or
|
||||
@@ -1587,8 +1651,8 @@ attempt_shell_completion (text, start, end)
|
||||
succeed. Don't bother if readline found a single quote and we are
|
||||
completing on the substring. */
|
||||
if (*text == '`' && rl_completion_quote_character != '\'' &&
|
||||
(in_command_position || (unclosed_pair (rl_line_buffer, start, "`") &&
|
||||
unclosed_pair (rl_line_buffer, end, "`"))))
|
||||
(in_command_position > 0 || (unclosed_pair (rl_line_buffer, start, "`") &&
|
||||
unclosed_pair (rl_line_buffer, end, "`"))))
|
||||
matches = rl_completion_matches (text, command_subst_completion_function);
|
||||
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
@@ -1596,7 +1660,7 @@ attempt_shell_completion (text, start, end)
|
||||
have_progcomps = prog_completion_enabled && (progcomp_size () > 0);
|
||||
iw_compspec = progcomp_search (INITIALWORD);
|
||||
if (matches == 0 &&
|
||||
(in_command_position == 0 || text[0] == '\0' || (in_command_position && iw_compspec)) &&
|
||||
(in_command_position == 0 || text[0] == '\0' || (in_command_position > 0 && iw_compspec)) &&
|
||||
current_prompt_string == ps1_prompt)
|
||||
{
|
||||
int s, e, s1, e1, os, foundcs;
|
||||
@@ -1718,7 +1782,7 @@ attempt_shell_completion (text, start, end)
|
||||
if (matches == 0)
|
||||
{
|
||||
dflags = 0;
|
||||
if (in_command_position)
|
||||
if (in_command_position > 0)
|
||||
dflags |= DEFCOMP_CMDPOS;
|
||||
matches = bash_default_completion (text, start, end, qc, dflags);
|
||||
}
|
||||
@@ -1872,10 +1936,17 @@ executable_completion (filename, searching_path)
|
||||
const char *filename;
|
||||
int searching_path;
|
||||
{
|
||||
char *f;
|
||||
char *f, c;
|
||||
int r;
|
||||
|
||||
/* This gets an unquoted filename, so we need to quote special characters
|
||||
in the filename before the completion hook gets it. */
|
||||
#if 0
|
||||
f = savestring (filename);
|
||||
#else
|
||||
c = 0;
|
||||
f = bash_quote_filename ((char *)filename, SINGLE_MATCH, &c);
|
||||
#endif
|
||||
bash_directory_completion_hook (&f);
|
||||
|
||||
r = searching_path ? executable_file (f) : executable_or_directory (f);
|
||||
@@ -1927,6 +1998,8 @@ command_word_completion_function (hint_text, state)
|
||||
temp = rl_variable_value ("completion-ignore-case");
|
||||
igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);
|
||||
|
||||
old_glob_ignore_case = glob_ignore_case;
|
||||
|
||||
if (glob_matches)
|
||||
{
|
||||
free (glob_matches);
|
||||
@@ -2112,6 +2185,8 @@ globword:
|
||||
{
|
||||
if (state == 0)
|
||||
{
|
||||
rl_filename_completion_desired = 1;
|
||||
|
||||
glob_ignore_case = igncase;
|
||||
glob_matches = shell_glob_filename (hint, 0);
|
||||
glob_ignore_case = old_glob_ignore_case;
|
||||
@@ -2232,10 +2307,16 @@ globword:
|
||||
|
||||
if (absolute_program (hint))
|
||||
{
|
||||
#if 0
|
||||
if (igncase == 0)
|
||||
match = strncmp (val, hint, hint_len) == 0;
|
||||
else
|
||||
match = strncasecmp (val, hint, hint_len) == 0;
|
||||
#else
|
||||
/* Why duplicate the comparison rl_filename_completion_function
|
||||
already performs? */
|
||||
match = 1;
|
||||
#endif
|
||||
|
||||
/* If we performed tilde expansion, restore the original
|
||||
filename. */
|
||||
@@ -2760,13 +2841,17 @@ static int
|
||||
history_and_alias_expand_line (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
char *new_line;
|
||||
char *new_line, *t;
|
||||
|
||||
new_line = 0;
|
||||
#if defined (BANG_HISTORY)
|
||||
new_line = history_expand_line_internal (rl_line_buffer);
|
||||
#endif
|
||||
|
||||
t = expand_string_dollar_quote (new_line ? new_line : rl_line_buffer, 0);
|
||||
FREE (new_line);
|
||||
new_line = t;
|
||||
|
||||
#if defined (ALIAS)
|
||||
if (new_line)
|
||||
{
|
||||
@@ -2798,7 +2883,7 @@ static int
|
||||
shell_expand_line (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
char *new_line;
|
||||
char *new_line, *t;
|
||||
WORD_LIST *expanded_string;
|
||||
WORD_DESC *w;
|
||||
|
||||
@@ -2807,6 +2892,10 @@ shell_expand_line (count, ignore)
|
||||
new_line = history_expand_line_internal (rl_line_buffer);
|
||||
#endif
|
||||
|
||||
t = expand_string_dollar_quote (new_line ? new_line : rl_line_buffer, 0);
|
||||
FREE (new_line);
|
||||
new_line = t;
|
||||
|
||||
#if defined (ALIAS)
|
||||
if (new_line)
|
||||
{
|
||||
@@ -3191,6 +3280,8 @@ bash_directory_expansion (dirname)
|
||||
free (d);
|
||||
*dirname = nd;
|
||||
}
|
||||
else
|
||||
free (d);
|
||||
}
|
||||
|
||||
/* If necessary, rewrite directory entry */
|
||||
@@ -3372,38 +3463,7 @@ bash_directory_completion_hook (dirname)
|
||||
return_value = should_expand_dirname = nextch = closer = 0;
|
||||
local_dirname = *dirname;
|
||||
|
||||
if (t = mbschr (local_dirname, '$'))
|
||||
{
|
||||
should_expand_dirname = '$';
|
||||
nextch = t[1];
|
||||
/* Deliberately does not handle the deprecated $[...] arithmetic
|
||||
expansion syntax */
|
||||
if (nextch == '(')
|
||||
closer = ')';
|
||||
else if (nextch == '{')
|
||||
closer = '}';
|
||||
else
|
||||
nextch = 0;
|
||||
|
||||
if (closer)
|
||||
{
|
||||
int p;
|
||||
char delims[2];
|
||||
|
||||
delims[0] = closer; delims[1] = 0;
|
||||
p = skip_to_delim (t, 1, delims, SD_NOJMP|SD_COMPLETE);
|
||||
if (t[p] != closer)
|
||||
should_expand_dirname = 0;
|
||||
}
|
||||
}
|
||||
else if (local_dirname[0] == '~')
|
||||
should_expand_dirname = '~';
|
||||
else
|
||||
{
|
||||
t = mbschr (local_dirname, '`');
|
||||
if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
|
||||
should_expand_dirname = '`';
|
||||
}
|
||||
should_expand_dirname = bash_check_expchar (local_dirname, 1, &nextch, &closer);
|
||||
|
||||
if (should_expand_dirname && directory_exists (local_dirname, 1))
|
||||
should_expand_dirname = 0;
|
||||
@@ -3422,24 +3482,8 @@ bash_directory_completion_hook (dirname)
|
||||
free (new_dirname);
|
||||
dispose_words (wl);
|
||||
local_dirname = *dirname;
|
||||
/* XXX - change rl_filename_quote_characters here based on
|
||||
should_expand_dirname/nextch/closer. This is the only place
|
||||
custom_filename_quote_characters is modified. */
|
||||
if (rl_filename_quote_characters && *rl_filename_quote_characters)
|
||||
{
|
||||
int i, j, c;
|
||||
i = strlen (default_filename_quote_characters);
|
||||
custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
|
||||
for (i = j = 0; c = default_filename_quote_characters[i]; i++)
|
||||
{
|
||||
if (c == should_expand_dirname || c == nextch || c == closer)
|
||||
continue;
|
||||
custom_filename_quote_characters[j++] = c;
|
||||
}
|
||||
custom_filename_quote_characters[j] = '\0';
|
||||
rl_filename_quote_characters = custom_filename_quote_characters;
|
||||
set_filename_bstab (rl_filename_quote_characters);
|
||||
}
|
||||
|
||||
set_filename_quote_chars (should_expand_dirname, nextch, closer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3494,7 +3538,16 @@ bash_directory_completion_hook (dirname)
|
||||
subsequent directory checks don't fail. */
|
||||
if (temp2 == 0 && dircomplete_spelling && dircomplete_expand)
|
||||
{
|
||||
size_t l1, l2;
|
||||
|
||||
temp2 = dirspell (temp1);
|
||||
l2 = STRLEN (temp2);
|
||||
/* Don't take matches if they are shorter than the original path */
|
||||
if (temp2 && l2 < strlen (temp1) && STREQN (temp1, temp2, l2))
|
||||
{
|
||||
free (temp2);
|
||||
temp2 = 0;
|
||||
}
|
||||
if (temp2)
|
||||
{
|
||||
free (temp1);
|
||||
@@ -3729,7 +3782,7 @@ bash_complete_filename_internal (what_to_do)
|
||||
rl_completion_func_t *orig_attempt_func;
|
||||
rl_icppfunc_t *orig_dir_func;
|
||||
rl_compignore_func_t *orig_ignore_func;
|
||||
/*const*/ char *orig_rl_completer_word_break_characters;
|
||||
const char *orig_rl_completer_word_break_characters;
|
||||
int r;
|
||||
|
||||
orig_func = rl_completion_entry_function;
|
||||
@@ -4099,6 +4152,95 @@ quote_word_break_chars (text)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return a character in DIRNAME that will cause shell expansion to be
|
||||
performed. If NEXTP is non-null, *NEXTP gets the expansion character that
|
||||
follows RET (e.g., '{' or `(' for `$'). If CLOSERP is non-null, *CLOSERP
|
||||
gets the character that should close <RET><NEXTP>. If NEED_CLOSER is non-
|
||||
zero, any expansion pair that isn't closed causes this function to
|
||||
return 0, which indicates that we didn't find an expansion character. It's
|
||||
used in case DIRNAME is going to be expanded. If DIRNAME is just going to
|
||||
be quoted, NEED_CLOSER will be 0. */
|
||||
static int
|
||||
bash_check_expchar (dirname, need_closer, nextp, closerp)
|
||||
char *dirname;
|
||||
int need_closer;
|
||||
int *nextp, *closerp;
|
||||
{
|
||||
char *t;
|
||||
int ret, n, c;
|
||||
|
||||
ret = n = c = 0;
|
||||
if (t = mbschr (dirname, '$'))
|
||||
{
|
||||
ret = '$';
|
||||
n = t[1];
|
||||
/* Deliberately does not handle the deprecated $[...] arithmetic
|
||||
expansion syntax */
|
||||
if (n == '(')
|
||||
c = ')';
|
||||
else if (n == '{')
|
||||
c = '}';
|
||||
else
|
||||
n = 0;
|
||||
|
||||
if (c && need_closer) /* XXX */
|
||||
{
|
||||
int p;
|
||||
char delims[2];
|
||||
|
||||
delims[0] = c; delims[1] = 0;
|
||||
p = skip_to_delim (t, 1, delims, SD_NOJMP|SD_COMPLETE);
|
||||
if (t[p] != c)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (dirname[0] == '~')
|
||||
ret = '~';
|
||||
else
|
||||
{
|
||||
t = mbschr (dirname, '`');
|
||||
if (t)
|
||||
{
|
||||
if (need_closer == 0)
|
||||
ret = '`';
|
||||
else if (unclosed_pair (dirname, strlen (dirname), "`") == 0)
|
||||
ret = '`';
|
||||
}
|
||||
}
|
||||
|
||||
if (nextp)
|
||||
*nextp = n;
|
||||
if (closerp)
|
||||
*closerp = c;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make sure EXPCHAR and, if non-zero, NEXTCH and CLOSER are not in the set
|
||||
of characters to be backslash-escaped. This is the only place
|
||||
custom_filename_quote_characters is modified. */
|
||||
static void
|
||||
set_filename_quote_chars (expchar, nextch, closer)
|
||||
int expchar, nextch, closer;
|
||||
{
|
||||
int i, j, c;
|
||||
|
||||
if (rl_filename_quote_characters && *rl_filename_quote_characters)
|
||||
{
|
||||
i = strlen (default_filename_quote_characters);
|
||||
custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
|
||||
for (i = j = 0; c = default_filename_quote_characters[i]; i++)
|
||||
{
|
||||
if (c == expchar || c == nextch || c == closer)
|
||||
continue;
|
||||
custom_filename_quote_characters[j++] = c;
|
||||
}
|
||||
custom_filename_quote_characters[j] = '\0';
|
||||
rl_filename_quote_characters = custom_filename_quote_characters;
|
||||
set_filename_bstab (rl_filename_quote_characters);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use characters in STRING to populate the table of characters that should
|
||||
be backslash-quoted. The table will be used for sh_backslash_quote from
|
||||
this file. */
|
||||
@@ -4127,6 +4269,7 @@ bash_quote_filename (s, rtype, qcp)
|
||||
{
|
||||
char *rtext, *mtext, *ret;
|
||||
int rlen, cs;
|
||||
int expchar, nextch, closer;
|
||||
|
||||
rtext = (char *)NULL;
|
||||
|
||||
@@ -4144,7 +4287,17 @@ bash_quote_filename (s, rtype, qcp)
|
||||
the word being completed contains newlines, since those are not
|
||||
quoted correctly using backslashes (a backslash-newline pair is
|
||||
special to the shell parser). */
|
||||
if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
|
||||
expchar = nextch = closer = 0;
|
||||
if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && dircomplete_expand == 0 &&
|
||||
(expchar = bash_check_expchar (s, 0, &nextch, &closer)))
|
||||
{
|
||||
/* Usually this will have been set by bash_directory_completion_hook, but
|
||||
there are rare cases where it will not be. */
|
||||
if (rl_filename_quote_characters != custom_filename_quote_characters)
|
||||
set_filename_quote_chars (expchar, nextch, closer);
|
||||
complete_fullquote = 0;
|
||||
}
|
||||
else if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
|
||||
cs = COMPLETE_SQUOTE;
|
||||
else if (*qcp == '"')
|
||||
cs = COMPLETE_DQUOTE;
|
||||
@@ -4294,12 +4447,28 @@ bash_execute_unix_command (count, key)
|
||||
SHELL_VAR *v;
|
||||
char ibuf[INT_STRLEN_BOUND(int) + 1];
|
||||
Keymap cmd_xmap;
|
||||
const char *kseq;
|
||||
size_t kslen;
|
||||
|
||||
kseq = rl_executing_keyseq;
|
||||
kslen = rl_key_sequence_length;
|
||||
|
||||
/* If we have a numeric argument, chop it off the front of the key sequence */
|
||||
if (count > 1 || rl_explicit_arg)
|
||||
{
|
||||
i = rl_trim_arg_from_keyseq (rl_executing_keyseq, rl_key_sequence_length, rl_get_keymap ());
|
||||
if (i > 0)
|
||||
{
|
||||
kseq = rl_executing_keyseq + i;
|
||||
kslen = rl_key_sequence_length - i;
|
||||
}
|
||||
}
|
||||
|
||||
/* First, we need to find the right command to execute. This is tricky,
|
||||
because we might have already indirected into another keymap, so we
|
||||
have to walk cmd_xmap using the entire key sequence. */
|
||||
cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ());
|
||||
cmd = (char *)rl_function_of_keyseq_len (rl_executing_keyseq, rl_key_sequence_length, cmd_xmap, &type);
|
||||
cmd = (char *)rl_function_of_keyseq_len (kseq, kslen, cmd_xmap, &type);
|
||||
|
||||
if (type == ISKMAP && (type = ((Keymap) cmd)[ANYOTHERKEY].type) == ISMACR)
|
||||
cmd = (char*)((Keymap) cmd)[ANYOTHERKEY].function;
|
||||
@@ -4336,6 +4505,14 @@ bash_execute_unix_command (count, key)
|
||||
v = bind_int_variable ("READLINE_MARK", value, 0);
|
||||
if (v)
|
||||
VSETATTR (v, att_exported);
|
||||
|
||||
if (count > 1 || rl_explicit_arg)
|
||||
{
|
||||
value = inttostr (count, ibuf, sizeof (ibuf));
|
||||
v = bind_int_variable ("READLINE_ARGUMENT", value, 0);
|
||||
if (v)
|
||||
VSETATTR (v, att_exported);
|
||||
}
|
||||
array_needs_making = 1;
|
||||
|
||||
save_parser_state (&ps);
|
||||
@@ -4358,6 +4535,7 @@ bash_execute_unix_command (count, key)
|
||||
check_unbind_variable ("READLINE_LINE");
|
||||
check_unbind_variable ("READLINE_POINT");
|
||||
check_unbind_variable ("READLINE_MARK");
|
||||
check_unbind_variable ("READLINE_ARGUMENT");
|
||||
array_needs_making = 1;
|
||||
|
||||
/* and restore the readline buffer and display after command execution. */
|
||||
@@ -4625,21 +4803,29 @@ bash_event_hook ()
|
||||
sig = terminating_signal;
|
||||
else if (interrupt_state)
|
||||
sig = SIGINT;
|
||||
else if (sigalrm_seen)
|
||||
else if (read_timeout && read_timeout->alrmflag)
|
||||
sig = SIGALRM;
|
||||
else if (RL_ISSTATE (RL_STATE_TIMEOUT)) /* just in case */
|
||||
{
|
||||
sig = SIGALRM;
|
||||
if (read_timeout)
|
||||
read_timeout->alrmflag = 1;
|
||||
}
|
||||
else
|
||||
sig = first_pending_trap ();
|
||||
|
||||
/* If we're going to longjmp to top_level, make sure we clean up readline.
|
||||
check_signals will call QUIT, which will eventually longjmp to top_level,
|
||||
calling run_interrupt_trap along the way. The check for sigalrm_seen is
|
||||
to clean up the read builtin's state. */
|
||||
if (terminating_signal || interrupt_state || sigalrm_seen)
|
||||
calling run_interrupt_trap along the way. The check against read_timeout
|
||||
is so we can clean up the read builtin's state. */
|
||||
if (terminating_signal || interrupt_state || (read_timeout && read_timeout->alrmflag))
|
||||
rl_cleanup_after_signal ();
|
||||
bashline_reset_event_hook ();
|
||||
|
||||
RL_UNSETSTATE (RL_STATE_TIMEOUT); /* XXX */
|
||||
|
||||
/* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. */
|
||||
if (posixly_correct && this_shell_builtin == read_builtin && sig == 2)
|
||||
if (posixly_correct && this_shell_builtin == read_builtin && sig == SIGINT)
|
||||
{
|
||||
last_command_exit_value = 128|SIGINT;
|
||||
throw_to_top_level ();
|
||||
|
||||
Reference in New Issue
Block a user