summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2018-11-23 15:32:57 -0500
committerChet Ramey <chet.ramey@case.edu>2018-11-23 15:32:57 -0500
commit2ae59c1134a75d5778997b7202b15b0586283042 (patch)
tree6a0fa496d41b222f5f69e3640d84932fb7a84778 /lib
parent2f5dfe5a18b4670eb4cea32c1c76295eb70a8865 (diff)
downloadbash-2ae59c1134a75d5778997b7202b15b0586283042.tar.gz
bash-5.0-beta2 releasebash-5.0-beta2
Diffstat (limited to 'lib')
-rw-r--r--lib/glob/glob.c2
-rw-r--r--lib/readline/bind.c101
-rw-r--r--lib/readline/display.c8
-rw-r--r--lib/readline/doc/rltech.texi15
-rw-r--r--lib/readline/doc/rluser.texi6
-rw-r--r--lib/readline/doc/version.texi6
-rw-r--r--lib/readline/histexpand.c8
-rw-r--r--lib/readline/histsearch.c20
-rw-r--r--lib/readline/input.c18
-rw-r--r--lib/readline/isearch.c37
-rw-r--r--lib/readline/keymaps.h3
-rw-r--r--lib/readline/kill.c24
-rw-r--r--lib/readline/readline.h3
-rw-r--r--lib/readline/rlprivate.h2
-rw-r--r--lib/readline/rltty.c1
-rw-r--r--lib/readline/search.c2
-rw-r--r--lib/readline/terminal.c1
-rw-r--r--lib/readline/undo.c27
-rw-r--r--lib/readline/vi_mode.c1
-rw-r--r--lib/sh/pathcanon.c2
-rw-r--r--lib/sh/pathphys.c2
21 files changed, 247 insertions, 42 deletions
diff --git a/lib/glob/glob.c b/lib/glob/glob.c
index 774435f1..22d90a5c 100644
--- a/lib/glob/glob.c
+++ b/lib/glob/glob.c
@@ -617,6 +617,8 @@ glob_vector (pat, dir, flags)
firstmalloc = 0;
nalloca = 0;
+ name_vector = NULL;
+
/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/
/* If PAT is empty, skip the loop, but return one (empty) filename. */
if (pat == 0 || *pat == '\0')
diff --git a/lib/readline/bind.c b/lib/readline/bind.c
index 2e05b460..57ae10f7 100644
--- a/lib/readline/bind.c
+++ b/lib/readline/bind.c
@@ -95,6 +95,9 @@ static const char *string_varname PARAMS((int));
static char *_rl_get_string_variable_value PARAMS((const char *));
static int substring_member_of_array PARAMS((const char *, const char * const *));
+static int _rl_get_keymap_by_name PARAMS((const char *));
+static int _rl_get_keymap_by_map PARAMS((Keymap));
+
static int currently_reading_init_file;
/* used only in this file */
@@ -2255,10 +2258,12 @@ glean_key_from_name (char *name)
}
/* Auxiliary functions to manage keymaps. */
-static const struct {
- const char * const name;
+struct name_and_keymap {
+ char *name;
Keymap map;
-} keymap_names[] = {
+};
+
+static struct name_and_keymap builtin_keymap_names[] = {
{ "emacs", emacs_standard_keymap },
{ "emacs-standard", emacs_standard_keymap },
{ "emacs-meta", emacs_meta_keymap },
@@ -2272,27 +2277,101 @@ static const struct {
{ (char *)0x0, (Keymap)0x0 }
};
+/* -1 for NULL entry */
+#define NUM_BUILTIN_KEYMAPS (sizeof (builtin_keymap_names) / sizeof (builtin_keymap_names[0]) - 1)
+
+static struct name_and_keymap *keymap_names = builtin_keymap_names;
+
+static int
+_rl_get_keymap_by_name (const char *name)
+{
+ register int i;
+
+ for (i = 0; keymap_names[i].name; i++)
+ if (_rl_stricmp (name, keymap_names[i].name) == 0)
+ return (i);
+ return -1;
+}
+
Keymap
rl_get_keymap_by_name (const char *name)
{
+ int i;
+
+ i = _rl_get_keymap_by_name (name);
+ return ((i >= 0) ? keymap_names[i].map : (Keymap) NULL);
+}
+
+static int
+_rl_get_keymap_by_map (Keymap map)
+{
register int i;
for (i = 0; keymap_names[i].name; i++)
- if (_rl_stricmp (name, keymap_names[i].name) == 0)
- return (keymap_names[i].map);
- return ((Keymap) NULL);
+ if (map == keymap_names[i].map)
+ return (i);
+ return -1;
}
char *
rl_get_keymap_name (Keymap map)
{
- register int i;
+ int i;
+
+ i = _rl_get_keymap_by_map (map);
+ return ((i >= 0) ? keymap_names[i].name : (char *)NULL);
+}
+
+int
+rl_set_keymap_name (const char *name, Keymap map)
+{
+ int i, ni, mi;
+
+ /* First check whether or not we're trying to rename a builtin keymap */
+ mi = _rl_get_keymap_by_map (map);
+ if (mi >= 0 && mi < NUM_BUILTIN_KEYMAPS)
+ return -1;
+
+ /* Then reject attempts to set one of the builtin names to a new map */
+ ni = _rl_get_keymap_by_name (name);
+ if (ni >= 0 && ni < NUM_BUILTIN_KEYMAPS)
+ return -1;
+
+ /* Renaming a keymap we already added */
+ if (mi >= 0) /* XXX - could be >= NUM_BUILTIN_KEYMAPS */
+ {
+ xfree (keymap_names[mi].name);
+ keymap_names[mi].name = savestring (name);
+ return mi;
+ }
+
+ /* Associating new keymap with existing name */
+ if (ni >= 0)
+ {
+ keymap_names[ni].map = map;
+ return ni;
+ }
+
for (i = 0; keymap_names[i].name; i++)
- if (map == keymap_names[i].map)
- return ((char *)keymap_names[i].name);
- return ((char *)NULL);
+ ;
+
+ if (keymap_names == builtin_keymap_names)
+ {
+ keymap_names = xmalloc ((i + 2) * sizeof (struct name_and_keymap));
+ memcpy (keymap_names, builtin_keymap_names, i * sizeof (struct name_and_keymap));
+ }
+ else
+ keymap_names = xrealloc (keymap_names, (i + 2) * sizeof (struct name_and_keymap));
+
+ keymap_names[i].name = savestring (name);
+ keymap_names[i].map = map;
+
+ keymap_names[i+1].name = NULL;
+ keymap_names[i+1].map = NULL;
+
+ return i;
}
-
+
void
rl_set_keymap (Keymap map)
{
diff --git a/lib/readline/display.c b/lib/readline/display.c
index b2ed1154..4c6cc00e 100644
--- a/lib/readline/display.c
+++ b/lib/readline/display.c
@@ -2873,14 +2873,14 @@ space_to_eol (int count)
void
_rl_clear_screen (void)
{
-#ifndef __DJGPP__
+#if defined (__DJGPP__)
+ ScreenClear ();
+ ScreenSetCursor (0, 0);
+#else
if (_rl_term_clrpag)
tputs (_rl_term_clrpag, 1, _rl_output_character_function);
else
rl_crlf ();
-#else
- ScreenClear ();
- ScreenSetCursor (0, 0);
#endif /* __DJGPP__ */
}
diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi
index baf036df..3624ea3e 100644
--- a/lib/readline/doc/rltech.texi
+++ b/lib/readline/doc/rltech.texi
@@ -720,6 +720,21 @@ Return the name matching @var{keymap}. @var{name} is one which would
be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}).
@end deftypefun
+@deftypefun void rl_set_keymap (const char *name, Keymap keymap)
+Set the name of @var{keymap}. This name will then be "registered" and
+available for use in a @code{set keymap} inputrc directive
+@pxref{Readline Init File}).
+The @var{name} may not be one of Readline's builtin names;
+you may not add a different name for one of Readline's builtin keymaps.
+Readline will make a copy of @var{name}.
+You may replace the name associated with a given keymap by calling this
+function two or more times with the same @var{keymap} argument.
+You can associate a registered name with a new keymap by calling this
+function two or more times with the same @var{name} argument.
+There is no way to remove a named keymap once the name has been
+registered.
+@end deftypefun
+
@node Binding Keys
@subsection Binding Keys
diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi
index 1acc8cda..a59bd144 100644
--- a/lib/readline/doc/rluser.texi
+++ b/lib/readline/doc/rluser.texi
@@ -606,7 +606,7 @@ If this variable has not been given a value, the characters @key{ESC} and
@item keymap
@vindex keymap
Sets Readline's idea of the current keymap for key binding commands.
-Acceptable @code{keymap} names are
+Built-in @code{keymap} names are
@code{emacs},
@code{emacs-standard},
@code{emacs-meta},
@@ -617,6 +617,7 @@ Acceptable @code{keymap} names are
@code{vi-insert}.
@code{vi} is equivalent to @code{vi-command} (@code{vi-move} is also a
synonym); @code{emacs} is equivalent to @code{emacs-standard}.
+Applications may add additional names.
The default value is @code{emacs}.
The value of the @code{editing-mode} variable also affects the
default keymap.
@@ -1850,6 +1851,9 @@ If no compspec is found for the full pathname, an attempt is made to
find a compspec for the portion following the final slash.
If those searches do not result in a compspec, any compspec defined with
the @option{-D} option to @code{complete} is used as the default.
+If there is no default compspec, Bash attempts alias expansion
+on the command word as a final resort, and attempts to find a compspec
+for the command word from any successful expansion
Once a compspec has been found, it is used to generate the list of
matching words.
diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi
index 79f41917..7e08db61 100644
--- a/lib/readline/doc/version.texi
+++ b/lib/readline/doc/version.texi
@@ -4,7 +4,7 @@ Copyright (C) 1988-2018 Free Software Foundation, Inc.
@set EDITION 8.0
@set VERSION 8.0
-@set UPDATED 6 July 2018
-@set UPDATED-MONTH July 2018
+@set UPDATED 18 September 2018
+@set UPDATED-MONTH September 2018
-@set LASTCHANGE Fri Jul 6 16:25:22 MDT 2018
+@set LASTCHANGE Tue Sep 18 13:08:12 EDT 2018
diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c
index 92b996f9..adcf5dcb 100644
--- a/lib/readline/histexpand.c
+++ b/lib/readline/histexpand.c
@@ -55,6 +55,8 @@
#define slashify_in_quotes "\\`\"$"
+#define fielddelim(c) (whitespace(c) || (c) == '\n')
+
typedef int _hist_search_func_t PARAMS((const char *, int));
static char error_pointer;
@@ -769,7 +771,7 @@ history_expand_internal (char *string, int start, int qc, int *end_index_ptr, ch
the last time. */
if (subst_bywords && si > we)
{
- for (; temp[si] && whitespace (temp[si]); si++)
+ for (; temp[si] && fielddelim (temp[si]); si++)
;
ws = si;
we = history_tokenize_word (temp, si);
@@ -1446,7 +1448,7 @@ history_tokenize_word (const char *string, int ind)
i = ind;
delimiter = nestdelim = 0;
- if (member (string[i], "()\n"))
+ if (member (string[i], "()\n")) /* XXX - included \n, but why? been here forever */
{
i++;
return i;
@@ -1604,7 +1606,7 @@ history_tokenize_internal (const char *string, int wind, int *indp)
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
{
/* Skip leading whitespace. */
- for (; string[i] && whitespace (string[i]); i++)
+ for (; string[i] && fielddelim (string[i]); i++)
;
if (string[i] == 0 || string[i] == history_comment_char)
return (result);
diff --git a/lib/readline/histsearch.c b/lib/readline/histsearch.c
index b6771fda..7a426c96 100644
--- a/lib/readline/histsearch.c
+++ b/lib/readline/histsearch.c
@@ -199,7 +199,7 @@ int
_hs_history_patsearch (const char *string, int direction, int flags)
{
char *pat;
- size_t len;
+ size_t len, start;
int ret, unescaped_backslash;
#if defined (HAVE_FNMATCH)
@@ -216,12 +216,26 @@ _hs_history_patsearch (const char *string, int direction, int flags)
}
if (unescaped_backslash)
return -1;
- pat = (char *)xmalloc (len + 2);
+ pat = (char *)xmalloc (len + 3);
+ /* If the search string is not anchored, we'll be calling fnmatch (assuming
+ we have it). Prefix a `*' to the front of the search string so we search
+ anywhere in the line. */
+ if ((flags & ANCHORED_SEARCH) == 0 && string[0] != '*')
+ {
+ pat[0] = '*';
+ start = 1;
+ len++;
+ }
+ else
+ {
+ start = 0;
+ }
+
/* Attempt to reduce the number of searches by tacking a `*' onto the end
of a pattern that doesn't have one. Assume a pattern that ends in a
backslash contains an even number of trailing backslashes; we check
above */
- strcpy (pat, string);
+ strcpy (pat + start, string);
if (pat[len - 1] != '*')
{
pat[len] = '*'; /* XXX */
diff --git a/lib/readline/input.c b/lib/readline/input.c
index 00916456..d4d57a81 100644
--- a/lib/readline/input.c
+++ b/lib/readline/input.c
@@ -102,15 +102,29 @@ static int rl_gather_tyi PARAMS((void));
/* Windows isatty returns true for every character device, including the null
device, so we need to perform additional checks. */
#if defined (_WIN32) && !defined (__CYGWIN__)
-#include <conio.h>
#include <io.h>
+#include <conio.h>
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
int
win32_isatty (int fd)
{
- return (_isatty (fd) ? ((((long) (HANDLE) _get_osfhandle (fd)) & 3) == 3) : 0);
+ if (_isatty(fd))
+ {
+ HANDLE h;
+ DWORD ignored;
+
+ if ((h = (HANDLE) _get_osfhandle (fd)) == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return 0;
+ }
+ if (GetConsoleMode (h, &ignored) != 0)
+ return 1;
+ }
+ errno = ENOTTY;
+ return 0;
}
#define isatty(x) win32_isatty(x)
diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c
index fa58e848..d6c59041 100644
--- a/lib/readline/isearch.c
+++ b/lib/readline/isearch.c
@@ -327,7 +327,10 @@ _rl_search_getchar (_rl_search_cxt *cxt)
int
_rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
{
- int n, wstart, wlen, limit, cval;
+ int n, wstart, wlen, limit, cval, incr;
+ char *paste;
+ size_t pastelen;
+ int j;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
@@ -398,6 +401,8 @@ add_character:
cxt->lastc = -5;
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
cxt->lastc = -6;
+ else if (f == rl_bracketed_paste_begin)
+ cxt->lastc = -7;
}
/* If we changed the keymap earlier while translating a key sequence into
@@ -620,22 +625,44 @@ add_character:
cxt->search_string[cxt->search_string_index] = '\0';
break;
+ case -7: /* bracketed paste */
+ paste = _rl_bracketed_text (&pastelen);
+ if (paste == 0 || *paste == 0)
+ {
+ free (paste);
+ break;
+ }
+ if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
+ {
+ cxt->search_string_size += pastelen + 2;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ }
+ strcpy (cxt->search_string + cxt->search_string_index, paste);
+ cxt->search_string_index += pastelen;
+ free (paste);
+ break;
+
/* Add character to search string and continue search. */
default:
- if (cxt->search_string_index + 2 >= cxt->search_string_size)
+#if defined (HANDLE_MULTIBYTE)
+ wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb);
+#else
+ wlen = 1;
+#endif
+ if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
- cxt->search_string_size += 128;
+ cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
- int j, l;
+ int j;
if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
else
- for (j = 0, l = RL_STRLEN (cxt->mb); j < l; )
+ for (j = 0; j < wlen; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
diff --git a/lib/readline/keymaps.h b/lib/readline/keymaps.h
index af8d5d99..1fa853d8 100644
--- a/lib/readline/keymaps.h
+++ b/lib/readline/keymaps.h
@@ -90,6 +90,9 @@ extern Keymap rl_get_keymap PARAMS((void));
/* Set the current keymap to MAP. */
extern void rl_set_keymap PARAMS((Keymap));
+/* Set the name of MAP to NAME */
+extern int rl_set_keymap_name PARAMS((const char *, Keymap));
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/readline/kill.c b/lib/readline/kill.c
index 9fdfc772..cf8ca932 100644
--- a/lib/readline/kill.c
+++ b/lib/readline/kill.c
@@ -670,16 +670,16 @@ rl_yank_last_arg (int count, int key)
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and insert the pasted text as a single unit without
interpretation. */
-int
-rl_bracketed_paste_begin (int count, int key)
+char *
+_rl_bracketed_text (size_t *lenp)
{
- int retval, c;
+ int c;
size_t len, cap;
char *buf;
- retval = 0;
len = 0;
buf = xmalloc (cap = 64);
+ buf[0] = '\0';
RL_SETSTATE (RL_STATE_MOREINPUT);
while ((c = rl_read_key ()) >= 0)
@@ -708,9 +708,23 @@ rl_bracketed_paste_begin (int count, int key)
if (len == cap)
buf = xrealloc (buf, cap + 1);
buf[len] = '\0';
- retval = rl_insert_text (buf) == len ? 0 : 1;
}
+ if (lenp)
+ *lenp = len;
+ return (buf);
+}
+
+int
+rl_bracketed_paste_begin (int count, int key)
+{
+ int retval, c;
+ size_t len, cap;
+ char *buf;
+
+ buf = _rl_bracketed_text (&len);
+ retval = rl_insert_text (buf) == len ? 0 : 1;
+
xfree (buf);
return (retval);
}
diff --git a/lib/readline/readline.h b/lib/readline/readline.h
index 4e08b2e9..da782716 100644
--- a/lib/readline/readline.h
+++ b/lib/readline/readline.h
@@ -357,6 +357,9 @@ extern Keymap rl_get_keymap_by_name PARAMS((const char *));
extern char *rl_get_keymap_name PARAMS((Keymap));
extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void));
+
+extern int rl_set_keymap_name PARAMS((const char *, Keymap));
+
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h
index 69943de5..e85e4d81 100644
--- a/lib/readline/rlprivate.h
+++ b/lib/readline/rlprivate.h
@@ -309,6 +309,8 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
#define BRACK_PASTE_INIT "\033[?2004h"
#define BRACK_PASTE_FINI "\033[?2004l\r"
+extern char *_rl_bracketed_text PARAMS((size_t *));
+
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_peek_macro_key PARAMS((void));
diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c
index 2ee36a7c..d0cd5727 100644
--- a/lib/readline/rltty.c
+++ b/lib/readline/rltty.c
@@ -396,7 +396,6 @@ save_tty_chars (TIOTYPE *tiop)
/* Currently this is only used on AIX */
static void
rltty_warning (char *msg)
- char *msg;
{
_rl_errmsg ("warning: %s", msg);
}
diff --git a/lib/readline/search.c b/lib/readline/search.c
index 64925611..c9c1f5d1 100644
--- a/lib/readline/search.c
+++ b/lib/readline/search.c
@@ -135,7 +135,7 @@ noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
sflags |= ANCHORED_SEARCH;
s++;
}
- ret = _hs_history_patsearch (string, dir, sflags);
+ ret = _hs_history_patsearch (s, dir, sflags);
}
else if (*string == '^')
ret = history_search_prefix (string + 1, dir);
diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c
index d9a6a999..e5573897 100644
--- a/lib/readline/terminal.c
+++ b/lib/readline/terminal.c
@@ -595,6 +595,7 @@ bind_termcap_arrow_keys (Keymap map)
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
+ rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode); /* Insert */
_rl_keymap = xkeymap;
}
diff --git a/lib/readline/undo.c b/lib/readline/undo.c
index 75874e5d..ae65d380 100644
--- a/lib/readline/undo.c
+++ b/lib/readline/undo.c
@@ -51,6 +51,8 @@
extern void _hs_replace_history_data PARAMS((int, histdata_t *, histdata_t *));
+extern HIST_ENTRY *_rl_saved_line_for_history;
+
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */
int _rl_doing_an_undo = 0;
@@ -166,7 +168,7 @@ _rl_copy_undo_list (UNDO_LIST *head)
int
rl_do_undo (void)
{
- UNDO_LIST *release;
+ UNDO_LIST *release, *search;
int waiting_for_begin, start, end;
HIST_ENTRY *cur, *temp;
@@ -223,6 +225,7 @@ rl_do_undo (void)
release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
+ release->next = 0; /* XXX */
/* If we are editing a history entry, make sure the change is replicated
in the history entry's line */
@@ -235,8 +238,30 @@ rl_do_undo (void)
xfree (temp);
}
+ /* Make sure there aren't any history entries with that undo list */
_hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
+ /* And make sure this list isn't anywhere in the saved line for history */
+ if (_rl_saved_line_for_history && _rl_saved_line_for_history->data)
+ {
+ /* Brute force; no finesse here */
+ search = (UNDO_LIST *)_rl_saved_line_for_history->data;
+ if (search == release)
+ _rl_saved_line_for_history->data = rl_undo_list;
+ else
+ {
+ while (search->next)
+ {
+ if (search->next == release)
+ {
+ search->next = rl_undo_list;
+ break;
+ }
+ search = search->next;
+ }
+ }
+ }
+
xfree (release);
}
while (waiting_for_begin);
diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c
index d6fa38e9..836371c9 100644
--- a/lib/readline/vi_mode.c
+++ b/lib/readline/vi_mode.c
@@ -198,6 +198,7 @@ void
rl_vi_start_inserting (int key, int repeat, int sign)
{
_rl_vi_set_last (key, repeat, sign);
+ rl_begin_undo_group (); /* ensure inserts aren't concatenated */
rl_vi_insertion_mode (1, key);
}
diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c
index f19bd55f..f9506dff 100644
--- a/lib/sh/pathcanon.c
+++ b/lib/sh/pathcanon.c
@@ -227,7 +227,7 @@ sh_canonpath (path, flags)
if (result[2] == '\0') /* short-circuit for bare `//' */
result[1] = '\0';
else
- strcpy (result, result + 1);
+ memmove (result, result + 1, strlen (result + 1) + 1);
}
return (result);
diff --git a/lib/sh/pathphys.c b/lib/sh/pathphys.c
index 26016b76..99390cef 100644
--- a/lib/sh/pathphys.c
+++ b/lib/sh/pathphys.c
@@ -245,7 +245,7 @@ error:
if (result[2] == '\0') /* short-circuit for bare `//' */
result[1] = '\0';
else
- strcpy (result, result + 1);
+ memmove (result, result + 1, strlen (result + 1) + 1);
}
return (result);