From bc371472444f900d44050414e3472f7349a7aec7 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 30 Jan 2017 15:50:08 -0500 Subject: [PATCH] commit bash-20170127 snapshot --- CWRU/CWRU.chlog | 18 ++++++++++++++++++ lib/readline/input.c | 11 ++++++++++- lib/readline/signals.c | 19 ++++++++++++++----- parse.y | 31 +++++++++++++------------------ patchlevel.h | 2 +- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index b8436d64..74a0463e 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13027,3 +13027,21 @@ subst.c after reading a double-quoted string, make sure the W_NOCOMSUB and W_NOPROCSUB flags make it to the recursive invocation. Fixes bug reported by Jens Heyens + + 1/23 + ---- +lib/readline/signals.c + - _rl_orig_sigset: original signal mask, set and restored by + rl_set_signals (rl_clear_signals doesn't block signals). If we + are not installing signal handlers, just save signal mask each + time rl_set_signals is called + +lib/readline/input.c + - rl_getc: use _rl_orig_sigmask in the call to pselect(), so we block + the set of signals originally blocked by the calling application. + Fixes bug reported by Frédéric Brière + +parse.y + - yy_readline_get: try to unset NONBLOCK mode on readline's input + file descriptor before calling readline(). Inspired by report from + Siteshwar Vashisht diff --git a/lib/readline/input.c b/lib/readline/input.c index 286897d7..10ce4e01 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -76,6 +76,10 @@ extern int errno; # define O_NDELAY O_NONBLOCK /* Posix style */ #endif +#if defined (HAVE_PSELECT) +extern sigset_t _rl_orig_sigset; +#endif + /* Non-null means it is a pointer to a function to run while waiting for character input. */ rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; @@ -512,10 +516,15 @@ rl_getc (stream) #endif result = 0; #if defined (HAVE_PSELECT) - sigemptyset (&empty_set); FD_ZERO (&readfds); FD_SET (fileno (stream), &readfds); +# if defined (HANDLE_SIGNALS) + result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset); +# else + sigemptyset (&empty_set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set); result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set); +# endif /* HANDLE_SIGNALS */ #endif if (result >= 0) result = read (fileno (stream), &c, sizeof (unsigned char)); diff --git a/lib/readline/signals.c b/lib/readline/signals.c index 927f5323..768c5d19 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -113,6 +113,10 @@ int _rl_susp_char = 0; static int signals_set_flag; static int sigwinch_set_flag; +#if defined (HAVE_POSIX_SIGNALS) +sigset_t _rl_orig_sigset; +#endif /* !HAVE_POSIX_SIGNALS */ + /* **************************************************************** */ /* */ /* Signal Handling */ @@ -442,8 +446,8 @@ rl_set_signals () if (rl_catch_signals && signals_set_flag == 0) { #if defined (HAVE_POSIX_SIGNALS) - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &bset, &oset); + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset); #endif rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); @@ -484,7 +488,14 @@ rl_set_signals () signals_set_flag = 1; #if defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); + sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL); +#endif + } + else if (rl_catch_signals == 0) + { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset); #endif } @@ -506,8 +517,6 @@ rl_clear_signals () if (rl_catch_signals && signals_set_flag == 1) { - sigemptyset (&dummy.sa_mask); - /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler, we should in theory not have to restore a handler where old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler diff --git a/parse.y b/parse.y index f900c672..151f0c6d 100644 --- a/parse.y +++ b/parse.y @@ -1455,6 +1455,7 @@ yy_readline_get () old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler); } + sh_unset_nodelay_mode (fileno (rl_instream)); /* just in case */ current_readline_line = readline (current_readline_prompt ? current_readline_prompt : ""); @@ -1617,19 +1618,9 @@ yy_stream_get () result = EOF; if (bash_input.location.file) { -#if 0 - if (interactive) - interrupt_immediately++; -#endif - /* XXX - don't need terminate_immediately; getc_with_restart checks for terminating signals itself if read returns < 0 */ result = getc_with_restart (bash_input.location.file); - -#if 0 - if (interactive) - interrupt_immediately--; -#endif } return (result); } @@ -2308,14 +2299,16 @@ shell_getc (remove_quoted_newline) #if 0 internal_warning ("shell_getc: ignored null byte in input"); #endif -if (bash_input.type == st_string) - { - if (i == 0) - shell_input_line_terminator = EOF; - shell_input_line[i] = '\0'; - c = EOF; - break; - } + /* If we get EOS while parsing a string, treat it as EOF so we + don't just keep looping. Happens very rarely */ + if (bash_input.type == st_string) + { + if (i == 0) + shell_input_line_terminator = EOF; + shell_input_line[i] = '\0'; + c = EOF; + break; + } continue; } @@ -3140,7 +3133,9 @@ read_token (command) we are eval'ing a string that is an incomplete command), return EOF */ if (character == '\0' && bash_input.type == st_string && expanding_alias() == 0) { +#if defined (DEBUG) itrace("shell_getc: bash_input.location.string = `%s'", bash_input.location.string); +#endif EOF_Reached = 1; return (yacc_EOF); } diff --git a/patchlevel.h b/patchlevel.h index 1bc098b8..93dbe0db 100644 --- a/patchlevel.h +++ b/patchlevel.h @@ -25,6 +25,6 @@ regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh looks for to find the patch level (for the sccs version string). */ -#define PATCHLEVEL 5 +#define PATCHLEVEL 12 #endif /* _PATCHLEVEL_H_ */