summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2015-07-29 16:17:30 -0400
committerChet Ramey <chet.ramey@case.edu>2015-07-29 16:17:30 -0400
commit7afeb718cb55ab9f224936a2b58cde07559eb59f (patch)
tree70d83f67540bccecf53cc0d152ed9d6860d08840
parent58a975cb0ceb2d178db286a8c1e2ca7be444dda0 (diff)
downloadbash-7afeb718cb55ab9f224936a2b58cde07559eb59f.tar.gz
commit bash-20150724 snapshot
-rw-r--r--CWRU/CWRU.chlog87
-rw-r--r--MANIFEST1
-rw-r--r--bashline.c2
-rw-r--r--doc/bash.17
-rw-r--r--doc/bashref.texi3
-rw-r--r--doc/version.texi6
-rw-r--r--input.c2
-rw-r--r--jobs.c2
-rw-r--r--lib/readline/callback.c32
-rw-r--r--lib/readline/readline.c8
-rw-r--r--lib/readline/readline.h3
-rw-r--r--lib/readline/rlprivate.h1
-rw-r--r--lib/readline/vi_mode.c49
-rw-r--r--lib/sh/shquote.c3
-rw-r--r--nojobs.c2
-rw-r--r--parse.y4
-rw-r--r--subst.c9
-rw-r--r--tests/exp.right12
-rw-r--r--tests/exp.tests1
-rw-r--r--tests/exp8.sub17
-rw-r--r--tests/run-all10
21 files changed, 236 insertions, 25 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index f6f4535..838a324 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -9072,7 +9072,8 @@ lib/readline/complete.c
7/17
----
lib/readline/readline.[ch]
- - rl_readline_state: now unsigned long
+ - rl_readline_state: now unsigned long, prepare for more than 32 states
+
7/18
----
@@ -9080,3 +9081,87 @@ lib/readline/history.h
- history_offset: now declared here, was always a global variable
- copy_history_entry: now declared here, part of the public interface
- alloc_history_entry: now declared here, part of the public interface
+
+ 7/20
+ ----
+lib/readline/readline.h
+ - RL_STATE_CHARSEARCH: new state, for vi mode character search. Was
+ previously handled by simply setting _rl_callback_func
+
+lib/readline/vi_mode.c
+ - rl_domove_motion_callback: split into two functions, remaining code
+ after _rl_dispatch call goes into new function
+ _rl_vi_domove_motion_cleanup
+ - rl_vi_char_search: set RL_STATE_CHARSEARCH
+ - rl_vi_char_search: sets `i2' member of callback data to the key used
+ to invoke the char search
+ - _rl_vi_callback_char_search: unset RL_STATE_CHARSEARCH after reading
+ the character to find
+ - _rl_vi_domove_motion_cleanup: make sure RL_STATE_VIMOTION is unset in
+ all cases where this function returns
+ - _rl_vi_domove_motion_cleanup: use `end' member of vi motion context
+ as value of rl_end to restore after adding blank at end of line in
+ rl_domove_motion_callback; avoids need to keep `old_end' and somehow
+ pass it between the two functions
+
+lib/readline/rlprivate.h
+ - _rl_vi_domove_motion_cleanup: new extern declaration
+
+lib/readline/callback.c
+ - rl_callback_read_char: handle RL_STATE_CHARSEARCH, including case
+ where char search is vi motion command for d/c/y/m and RL_STATE_VIMOTION
+ is set when this is called. Last of set of fixes for bug reported
+ by Carlos Pita <carlosjosepita@gmail.com> with vi-mode `dty' command
+ in callback mode
+
+ 7/21
+ ----
+subst.c
+ - command_substitute, process_substitute: add QUIT call in the child
+ after restoring original signal handlers to catch post-fork SIGINT
+ or terminating signal
+
+jobs.c,nojobs.c
+ - make_child: after forking, clear interrupt_state in child
+ before restoring signal mask so children get their own set of
+ interrupts
+
+ 7/22
+ ----
+lib/sh/shquote.c
+ - sh_double_quote: since all uses of the return value from this function
+ are for display and not subject to subsequent expansion, we don't
+ need to protect CTLESC and CTLNUL with CTLESC. Bug report and fix
+ from isabella parakiss <izaberina@gmail.com>
+
+parse.y
+ - decode_prompt_string: need to protect literal instances of CTLESC
+ and CTLNUL with CTLESC, even if they are not coming out of one of
+ the backslash-expansions
+
+subst.c
+ - make_internal_declare: fixed memory leak; make_internal_declare should
+ free the memory it allocates to construct the word list. From Red
+ Hat bug 1245233; https://bugzilla.redhat.com/show_bug.cgi?id=1245233
+
+lib/readline/readline.c
+ - _rl_dispatch_subseq: when checking whether an ESC in vi insert mode
+ should be treated as part of a key sequence or as a single char,
+ make sure we are getting input from the keyboard before we check
+ _rl_input_queued(). If we are getting input from a macro, this
+ causes a needless delay. Report from Carlos Pita
+ <carlosjosepita@gmail.com>
+
+ 7/23
+ ----
+input.c
+ - save_bash_input: before checking to see whether or not a new fd has a
+ stale associated buffer, make sure that the new fd is within bounds.
+ Bug report and fix from Alexey Makhalov <makhaloff@gmail.com>
+
+
+ 7/24
+ ----
+doc/{bash.1,bashref.texi}
+ - note that the `return' builtin accepts arguments beginning with `-'
+ without requiring `--'
diff --git a/MANIFEST b/MANIFEST
index dc28e04..b839974 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -959,6 +959,7 @@ tests/exp4.sub f
tests/exp5.sub f
tests/exp6.sub f
tests/exp7.sub f
+tests/exp8.sub f
tests/exportfunc.tests f
tests/exportfunc.right f
tests/exportfunc1.sub f
diff --git a/bashline.c b/bashline.c
index 5f9f6d4..9d4f0a0 100644
--- a/bashline.c
+++ b/bashline.c
@@ -3103,7 +3103,7 @@ directory_exists (dirname)
struct stat sb;
/* First, dequote the directory name */
- new_dirname = bash_dequote_filename (dirname, rl_completion_quote_character);
+ new_dirname = bash_dequote_filename ((char *)dirname, rl_completion_quote_character);
dirlen = STRLEN (new_dirname);
if (new_dirname[dirlen - 1] == '/')
new_dirname[dirlen - 1] = '\0';
diff --git a/doc/bash.1 b/doc/bash.1
index 97152c5..e577f5d 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Thu Jun 11 16:26:00 EDT 2015
+.\" Last Change: Fri Jul 24 11:33:12 EDT 2015
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2015 June 11" "GNU Bash 4.4"
+.TH BASH 1 "2015 July 24" "GNU Bash 4.4"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -6944,7 +6944,8 @@ accepts
to signify the end of the options.
The \fB:\fP, \fBtrue\fP, \fBfalse\fP, and \fBtest\fP builtins
do not accept options and do not treat \fB\-\-\fP specially.
-The \fBexit\fP, \fBlogout\fP, \fBbreak\fP, \fBcontinue\fP, \fBlet\fP,
+The \fBexit\fP, \fBlogout\fP, \fBreturn\fP,
+\fBbreak\fP, \fBcontinue\fP, \fBlet\fP,
and \fBshift\fP builtins accept and process arguments beginning with
\fB\-\fP without requiring \fB\-\-\fP.
Other builtins that accept arguments but are not specified as accepting
diff --git a/doc/bashref.texi b/doc/bashref.texi
index 93ad4a5..f2de995 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -3236,7 +3236,8 @@ options preceded by @samp{-} accepts @samp{--}
to signify the end of the options.
The @code{:}, @code{true}, @code{false}, and @code{test}
builtins do not accept options and do not treat @samp{--} specially.
-The @code{exit}, @code{logout}, @code{break}, @code{continue}, @code{let},
+The @code{exit}, @code{logout}, @code{return},
+@code{break}, @code{continue}, @code{let},
and @code{shift} builtins accept and process arguments beginning
with @samp{-} without requiring @samp{--}.
Other builtins that accept arguments but are not specified as accepting
diff --git a/doc/version.texi b/doc/version.texi
index 244d4af..7049fa8 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -2,10 +2,10 @@
Copyright (C) 1988-2015 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Thu Jun 11 16:25:43 EDT 2015
+@set LASTCHANGE Fri Jul 24 11:32:31 EDT 2015
@set EDITION 4.4
@set VERSION 4.4
-@set UPDATED 11 June 2015
-@set UPDATED-MONTH June 2015
+@set UPDATED 24 July 2015
+@set UPDATED-MONTH July 2015
diff --git a/input.c b/input.c
index 14c6f4e..2a9ca26 100644
--- a/input.c
+++ b/input.c
@@ -272,7 +272,7 @@ save_bash_input (fd, new_fd)
return -1;
}
- if (buffers[nfd])
+ if (nfd < nbuffers && buffers[nfd])
{
/* What's this? A stray buffer without an associated open file
descriptor? Free up the buffer and report the error. */
diff --git a/jobs.c b/jobs.c
index 27c578d..ab0cc11 100644
--- a/jobs.c
+++ b/jobs.c
@@ -1841,6 +1841,8 @@ make_child (command, async_p)
unset_bash_input (0);
#endif /* BUFFERED_INPUT */
+ CLRINTERRUPT; /* XXX - children have their own interrupt state */
+
/* Restore top-level signal mask. */
sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
diff --git a/lib/readline/callback.c b/lib/readline/callback.c
index 0fc3f90..ec48b76 100644
--- a/lib/readline/callback.c
+++ b/lib/readline/callback.c
@@ -161,6 +161,36 @@ rl_callback_read_char ()
CALLBACK_READ_RETURN ();
}
#if defined (VI_MODE)
+ /* States that can occur while in state VIMOTION have to be checked
+ before RL_STATE_VIMOTION */
+ else if (RL_ISSTATE (RL_STATE_CHARSEARCH))
+ {
+ int k;
+
+ k = _rl_callback_data->i2;
+
+ eof = (*_rl_callback_func) (_rl_callback_data);
+ /* If the function `deregisters' itself, make sure the data is
+ cleaned up. */
+ if (_rl_callback_func == 0) /* XXX - just sanity check */
+ {
+ if (_rl_callback_data)
+ {
+ _rl_callback_data_dispose (_rl_callback_data);
+ _rl_callback_data = 0;
+ }
+ }
+
+ /* Messy case where vi motion command can be char search */
+ if (RL_ISSTATE (RL_STATE_VIMOTION))
+ {
+ _rl_vi_domove_motion_cleanup (k, _rl_vimvcxt);
+ _rl_internal_char_cleanup ();
+ CALLBACK_READ_RETURN ();
+ }
+
+ _rl_internal_char_cleanup ();
+ }
else if (RL_ISSTATE (RL_STATE_VIMOTION))
{
eof = _rl_vi_domove_callback (_rl_vimvcxt);
@@ -311,6 +341,8 @@ rl_callback_sigcleanup ()
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
RL_UNSETSTATE (RL_STATE_MULTIKEY);
+ if (RL_ISSTATE (RL_STATE_CHARSEARCH))
+ RL_UNSETSTATE (RL_STATE_CHARSEARCH);
_rl_callback_func = 0;
}
diff --git a/lib/readline/readline.c b/lib/readline/readline.c
index 0a54dc3..ce72501 100644
--- a/lib/readline/readline.c
+++ b/lib/readline/readline.c
@@ -916,8 +916,10 @@ _rl_dispatch_subseq (key, map, got_subseq)
default) or a timeout determined by the value of `keyseq-timeout' */
/* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
takes microseconds, so multiply by 1000 */
- if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap
- && _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0)
+ if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap &&
+ (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 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
@@ -954,7 +956,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
/* Tentative inter-character timeout for potential multi-key
sequences? If no input within timeout, abort sequence and
act as if we got non-matching input. */
- /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
+ /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued[B
takes microseconds, so multiply by 1000 */
if (_rl_keyseq_timeout > 0 &&
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
diff --git a/lib/readline/readline.h b/lib/readline/readline.h
index e1773fa..fa458be 100644
--- a/lib/readline/readline.h
+++ b/lib/readline/readline.h
@@ -870,7 +870,8 @@ extern int rl_inhibit_completion;
#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */
-#define RL_STATE_REDISPLAYING 0x0800000 /* updating terminal display */
+#define RL_STATE_CHARSEARCH 0x0800000 /* vi mode char search */
+#define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */
#define RL_STATE_DONE 0x1000000 /* done; accepted line */
diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h
index 9b859f9..55b7e6b 100644
--- a/lib/readline/rlprivate.h
+++ b/lib/readline/rlprivate.h
@@ -427,6 +427,7 @@ extern int _rl_vi_textmod_command PARAMS((int));
extern int _rl_vi_motion_command PARAMS((int));
extern void _rl_vi_done_inserting PARAMS((void));
extern int _rl_vi_domove_callback PARAMS((_rl_vimotion_cxt *));
+extern int _rl_vi_domove_motion_cleanup PARAMS((int, _rl_vimotion_cxt *));
/*************************************************************************
* Undocumented private variables *
diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c
index cae80ca..dcde2fb 100644
--- a/lib/readline/vi_mode.c
+++ b/lib/readline/vi_mode.c
@@ -1096,28 +1096,55 @@ static int
rl_domove_motion_callback (m)
_rl_vimotion_cxt *m;
{
- int c, save, r;
- int old_end;
+ int c;
_rl_vi_last_motion = c = m->motion;
/* Append a blank character temporarily so that the motion routines
- work right at the end of the line. */
- old_end = rl_end;
+ work right at the end of the line. Original value of rl_end is saved
+ as m->end. */
rl_line_buffer[rl_end++] = ' ';
rl_line_buffer[rl_end] = '\0';
_rl_dispatch (c, _rl_keymap);
- /* Remove the blank that we added. */
- rl_end = old_end;
+#if defined (READLINE_CALLBACKS)
+ if (RL_ISSTATE (RL_STATE_CALLBACK))
+ {
+ /* Messy case where char search can be vi motion command; see rest of
+ details in callback.c. vi_char_search and callback_char_search just
+ set and unset the CHARSEARCH state. This is where any vi motion
+ command that needs to set its own state should be handled, with any
+ corresponding code to manage that state in callback.c */
+ if (RL_ISSTATE (RL_STATE_CHARSEARCH))
+ return 0;
+ else
+ return (_rl_vi_domove_motion_cleanup (c, m));
+ }
+#endif
+
+ return (_rl_vi_domove_motion_cleanup (c, m));
+}
+
+int
+_rl_vi_domove_motion_cleanup (c, m)
+ int c;
+ _rl_vimotion_cxt *m;
+{
+ int r;
+
+ /* Remove the blank that we added in rl_domove_motion_callback. */
+ rl_end = m->end;
rl_line_buffer[rl_end] = '\0';
if (rl_point > rl_end)
rl_point = rl_end;
/* No change in position means the command failed. */
if (rl_mark == rl_point)
- return (-1);
+ {
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ return (-1);
+ }
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
word. If we are not at the end of the line, and we are on a
@@ -1625,7 +1652,10 @@ _rl_vi_callback_char_search (data)
#endif
if (c <= 0)
- return -1;
+ {
+ RL_UNSETSTATE (RL_STATE_CHARSEARCH);
+ return -1;
+ }
#if !defined (HANDLE_MULTIBYTE)
_rl_vi_last_search_char = c;
@@ -1633,6 +1663,7 @@ _rl_vi_callback_char_search (data)
_rl_callback_func = 0;
_rl_want_redisplay = 1;
+ RL_UNSETSTATE (RL_STATE_CHARSEARCH);
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
@@ -1697,7 +1728,9 @@ rl_vi_char_search (count, key)
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
+ _rl_callback_data->i2 = key;
_rl_callback_func = _rl_vi_callback_char_search;
+ RL_SETSTATE (RL_STATE_CHARSEARCH);
return (0);
}
#endif
diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c
index 782a1f5..92b0e11 100644
--- a/lib/sh/shquote.c
+++ b/lib/sh/shquote.c
@@ -148,8 +148,11 @@ sh_double_quote (string)
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
+#if 0
+ /* Assume that the string will not be further expanded. */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
+#endif
*r++ = c;
}
diff --git a/nojobs.c b/nojobs.c
index 58a9b2f..d8b85bf 100644
--- a/nojobs.c
+++ b/nojobs.c
@@ -547,6 +547,8 @@ make_child (command, async_p)
unset_bash_input (0);
#endif /* BUFFERED_INPUT */
+ CLRINTERRUPT; /* XXX - children have their own interrupt state */
+
#if defined (HAVE_POSIX_SIGNALS)
/* Restore top-level signal mask. */
sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
diff --git a/parse.y b/parse.y
index 562935e..75668a0 100644
--- a/parse.y
+++ b/parse.y
@@ -5629,6 +5629,10 @@ not_escape:
else
{
RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
+ /* dequote_string should take care of removing this if we are not
+ performing the rest of the word expansions. */
+ if (c == CTLESC || c == CTLNUL)
+ result[result_index++] = CTLESC;
result[result_index++] = c;
result[result_index] = '\0';
}
diff --git a/subst.c b/subst.c
index 98f09d5..d445c2c 100644
--- a/subst.c
+++ b/subst.c
@@ -5453,6 +5453,7 @@ process_substitute (string, open_for_read_in_child)
free_pushed_string_input ();
/* Cancel traps, in trap.c. */
restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
+ QUIT; /* catch any interrupts we got post-fork */
setup_async_signals ();
subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
}
@@ -5766,6 +5767,7 @@ command_substitute (string, quoted)
trap strings. Set a flag noting that we have to free the
trap strings if we run trap to change a signal disposition. */
reset_signal_handlers ();
+ QUIT; /* catch any interrupts we got post-fork */
subshell_environment |= SUBSHELL_RESETTRAP;
}
@@ -10004,7 +10006,7 @@ make_internal_declare (word, option)
char *word;
char *option;
{
- int t;
+ int t, r;
WORD_LIST *wl;
WORD_DESC *w;
@@ -10016,7 +10018,10 @@ make_internal_declare (word, option)
wl = make_word_list (w, (WORD_LIST *)NULL);
wl = make_word_list (make_word (option), wl);
- return (declare_builtin (wl));
+ r = declare_builtin (wl);
+
+ dispose_words (wl);
+ return r;
}
#endif
diff --git a/tests/exp.right b/tests/exp.right
index b9315a9..3f9d9ed 100644
--- a/tests/exp.right
+++ b/tests/exp.right
@@ -218,3 +218,15 @@ argv[3] = <^C>
argv[4] = <^C>
./exp7.sub: line 10: INFORM: dequote_string: string with bare CTLESC
argv[1] = <^A>
+argv[1] = <x^Ay^?z>
+argv[1] = <x^Ay^?z>
+declare -- var="xyz"
+argv[1] = <declare>
+argv[2] = <-->
+argv[3] = <var="x^Ay^?z">
+declare -- var="x\001y\177z"$
+argv[1] = <$'x\001y\177z'>
+argv[1] = <x^Ay^?z>
+var=$'x\001y\177z'$
+argv[1] = <x^Ay^?z>
+declare -a array=([0]="x\001y\177z")$
diff --git a/tests/exp.tests b/tests/exp.tests
index 54bf722..e6e2bc5 100644
--- a/tests/exp.tests
+++ b/tests/exp.tests
@@ -403,3 +403,4 @@ ${THIS_SH} ./exp5.sub
${THIS_SH} ./exp6.sub
${THIS_SH} ./exp7.sub
+${THIS_SH} ./exp8.sub
diff --git a/tests/exp8.sub b/tests/exp8.sub
new file mode 100644
index 0000000..34d9ef1
--- /dev/null
+++ b/tests/exp8.sub
@@ -0,0 +1,17 @@
+var=$'x\001y\177z'
+
+recho "$var"
+recho $var
+
+declare -p var
+recho $(declare -p var)
+
+declare -p var | sed -n l
+
+recho ${var@Q}
+recho ${var@P}
+echo ${var@A} | sed -n l
+
+array=( "$var" )
+recho ${array[@]}
+echo ${array[@]@A} | sed -n l
diff --git a/tests/run-all b/tests/run-all
index d3f3a0e..f1a4397 100644
--- a/tests/run-all
+++ b/tests/run-all
@@ -1,5 +1,13 @@
#! /bin/sh
+: ${TMPDIR:=/tmp}
+export TMPDIR
+
+BASH_TMPOUT=/tmp/xx # for now
+export BASH_TMPOUT
+
+trap 'rm -f $BASH_TMPOUT' 0
+
PATH=.:$PATH # just to get recho/zecho/printenv if not run via `make tests'
export PATH
@@ -13,7 +21,7 @@ export THIS_SH
${THIS_SH} ./version
-rm -f /tmp/xx
+rm -f ${BASH_TMPOUT}
echo Any output from any test, unless otherwise noted, indicates a possible anomaly