diff options
author | Chet Ramey <chet.ramey@case.edu> | 2023-01-24 11:14:22 -0500 |
---|---|---|
committer | Chet Ramey <chet.ramey@case.edu> | 2023-01-24 11:14:22 -0500 |
commit | d0bc56a32584da615e5baff315d26ac7139a6ae2 (patch) | |
tree | 63bec3c93f76846a246528be6cf8f624da6d0ba6 | |
parent | a37b2af98533ace0ca90b3a2187481ee08e2615f (diff) | |
download | bash-d0bc56a32584da615e5baff315d26ac7139a6ae2.tar.gz |
allow async ignored signals to be reset to SIG_DFL; give rl_input_available_hook precedence in readline:rl_gather_tyi
-rw-r--r-- | CWRU/CWRU.chlog | 24 | ||||
-rw-r--r-- | CWRU/misc/sigs.c | 8 | ||||
-rw-r--r-- | CWRU/misc/sigstat.c | 9 | ||||
-rw-r--r-- | lib/readline/doc/rltech.texi | 2 | ||||
-rw-r--r-- | lib/readline/doc/version.texi | 4 | ||||
-rw-r--r-- | lib/readline/input.c | 66 | ||||
-rw-r--r-- | lib/readline/rlprivate.h | 16 | ||||
-rw-r--r-- | subst.c | 14 | ||||
-rw-r--r-- | trap.c | 11 |
9 files changed, 111 insertions, 43 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index ebf5eafe..6e029e1c 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -5105,3 +5105,27 @@ lib/readline/{histexpand.c,history.h} lib/readline/doc/{history.3,hstech.texi} - history_expansion: change description to note new const first arg + + 1/21 + ---- +lib/readline/input.c + - rl_gather_tyi: move call to rl_input_available_hook to the top, + giving it first shot. There's still no way for it to set chars_avail. + Conditionalize the rest of the input methods based on whether the + result == -1. + +lib/readline/rl_private.h + - move the decision making about RL_TIMEOUT_USE_SELECT/RL_TIMEOUT_USE_SIGALRM + here from input.c + + 1/23 + ---- +trap.c + - restore_default_signal: if we have a signal that's not trapped, but + is a signal that is set to SIG_ASYNCSIG, POSIX interp 751 requires + the shell to allow it to be reset to the default, even though it + wasn't already trapped + +subst.c + - do_assignment_internal: don't allocate new memory for NAME, just + modify and restore it in place diff --git a/CWRU/misc/sigs.c b/CWRU/misc/sigs.c index bae93f8a..c575de90 100644 --- a/CWRU/misc/sigs.c +++ b/CWRU/misc/sigs.c @@ -20,16 +20,16 @@ #include <signal.h> #include <stdio.h> +#include <stdlib.h> extern const char * const sys_siglist[]; typedef void sighandler(); -main(argc, argv) -int argc; -char **argv; +int +main(int argc, char **argv) { - register int i; + int i; sighandler *h; for (i = 1; i < NSIG; i++) { diff --git a/CWRU/misc/sigstat.c b/CWRU/misc/sigstat.c index 9135baa4..41ed361e 100644 --- a/CWRU/misc/sigstat.c +++ b/CWRU/misc/sigstat.c @@ -26,14 +26,18 @@ #include <sys/types.h> #include <signal.h> #include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> -extern char *strrchr(); static char *signames[NSIG]; char *progname; -void sigstat(); +void sigstat(int); +void init_signames(void); +int main(argc, argv) int argc; char **argv; @@ -83,6 +87,7 @@ int sig; printf("%s: signal is trapped (?)\n", signame); } +void init_signames() { register int i; diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index a93f77da..f40bc2bd 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -476,6 +476,8 @@ The default hook checks @code{rl_instream}; if an application is using a different input source, it should set the hook appropriately. Readline queries for available input when implementing intra-key-sequence timeouts during input and incremental searches. +This function must return zero if there is no input available, and non-zero +if input is available. This may use an application-specific timeout before returning a value; Readline uses the value passed to @code{rl_set_keyboard_input_timeout()} or the value of the user-settable @var{keyseq-timeout} variable. diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 0d4af12e..2b80d343 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -5,7 +5,7 @@ Copyright (C) 1988-2023 Free Software Foundation, Inc. @set EDITION 8.2 @set VERSION 8.2 -@set UPDATED 19 January 2023 +@set UPDATED 21 January 2023 @set UPDATED-MONTH January 2023 -@set LASTCHANGE Thu Jan 19 17:22:06 EST 2023 +@set LASTCHANGE Sat Jan 21 17:10:44 EST 2023 diff --git a/lib/readline/input.c b/lib/readline/input.c index 186e0fac..229474ff 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -138,13 +138,7 @@ win32_isatty (int fd) /* Readline timeouts */ -/* I don't know how to set a timeout for _getch() in MinGW32, so we use - SIGALRM. */ -#if (defined (HAVE_PSELECT) || defined (HAVE_SELECT)) && !defined (__MINGW32__) -# define RL_TIMEOUT_USE_SELECT -#else -# define RL_TIMEOUT_USE_SIGALRM -#endif +/* We now define RL_TIMEOUT_USE_SELECT or RL_TIMEOUT_USE_SIGALRM in rlprivate.h */ int rl_set_timeout (unsigned int, unsigned int); int rl_timeout_remaining (unsigned int *, unsigned int *); @@ -259,37 +253,44 @@ rl_gather_tyi (void) input = 0; tty = fileno (rl_instream); + /* Move this up here to give it first shot, but it can't set chars_avail */ + /* XXX - need rl_chars_available_hook? */ + if (rl_input_available_hook) + { + result = (*rl_input_available_hook) (); + if (result == 0) + result = -1; + } + #if defined (HAVE_PSELECT) || defined (HAVE_SELECT) - FD_ZERO (&readfds); - FD_ZERO (&exceptfds); - FD_SET (tty, &readfds); - FD_SET (tty, &exceptfds); - USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); + if (result == -1) + { + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); #if defined (RL_TIMEOUT_USE_SELECT) - result = _rl_timeout_select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout, NULL); + result = _rl_timeout_select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout, NULL); #else - result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); + result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); #endif - if (result <= 0) - return 0; /* Nothing to read. */ + if (result <= 0) + return 0; /* Nothing to read. */ + } #endif - result = -1; - errno = 0; #if defined (FIONREAD) - result = ioctl (tty, FIONREAD, &chars_avail); - if (result == -1 && errno == EIO) - return -1; if (result == -1) - chars_avail = 0; -#endif - - if (result == -1 && rl_input_available_hook) { - result = (*rl_input_available_hook) (); - if (result == 0) - result = -1; + errno = 0; + result = ioctl (tty, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; + if (result == -1) + chars_avail = 0; } +#endif #if defined (O_NDELAY) if (result == -1) @@ -315,8 +316,11 @@ rl_gather_tyi (void) #if defined (__MINGW32__) /* Use getch/_kbhit to check for available console input, in the same way that we read it normally. */ - chars_avail = isatty (tty) ? _kbhit () : 0; - result = 0; + if (result == -1) + { + chars_avail = isatty (tty) ? _kbhit () : 0; + result = 0; + } #endif /* If there's nothing available, don't waste time trying to read @@ -658,7 +662,7 @@ rl_timeout_remaining (unsigned int *secs, unsigned int *usecs) /* This should only be called if RL_TIMEOUT_USE_SELECT is defined. */ -#if defined (HAVE_PSELECT) || defined (HAVE_SELECT) +#if defined (RL_TIMEOUT_USE_SELECT) int _rl_timeout_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout, const sigset_t *sigmask) { diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 15a75c5b..77a4d8c6 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -303,8 +303,22 @@ extern int _rl_pushed_input_available (void); extern int _rl_timeout_init (void); extern int _rl_timeout_handle_sigalrm (void); -#if defined (_POSIXSELECT_H_) && !defined (__MINGW32__) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT)) + +#if defined (_POSIXSELECT_H_) /* use as a sentinel for fd_set, struct timeval, and sigset_t definitions */ + +#if defined (__MINGW32__) +# define RL_TIMEOUT_USE_SIGALRM +#elif defined (HAVE_SELECT) || defined (HAVE_PSELECT) +# define RL_TIMEOUT_USE_SELECT +#elif defined (_MSC_VER) +/* can't use select/pselect or SIGALRM, so no timeouts */ +#else +# define RL_TIMEOUT_USE_SIGALRM +#endif + +#endif +#if defined (RL_TIMEOUT_USE_SELECT) extern int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *); #endif @@ -3461,7 +3461,7 @@ do_assignment_internal (const WORD_DESC *word, int expand) char *t; int ni; #endif - const char *string; + char *string; if (word == 0 || word->word == 0) return 0; @@ -3469,7 +3469,7 @@ do_assignment_internal (const WORD_DESC *word, int expand) appendop = assign_list = aflags = 0; string = word->word; offset = assignment (string, 0); - name = savestring (string); + name = string; value = (char *)NULL; if (name[offset] == '=') @@ -3512,12 +3512,20 @@ do_assignment_internal (const WORD_DESC *word, int expand) name[offset - 1] = '\0'; } -#define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0) +#define ASSIGN_RETURN(r) \ +do \ +{ \ + FREE (value); \ + if (appendop) name[offset - 1] = '+'; \ + name[offset] = '='; \ + return (r); \ +} while (0) if (appendop) aflags |= ASS_APPEND; #if defined (ARRAY_VARS) + /* could use strchr, since variable names can't yet contain multibyte characters */ if (t = mbschr (name, LBRACK)) { if (assign_list) @@ -902,6 +902,17 @@ restore_default_signal (int sig) if (sigmodes[sig] & SIG_HARD_IGNORE) return; + /* Even if the signal is not trapped, POSIX interp 751 requires that we + allow `trap - SIGINT' to reset the signal disposition for SIGINT to + SIG_DFL. */ + if ((sigmodes[sig] & (SIG_TRAPPED|SIG_ASYNCSIG|SIG_NO_TRAP)) == SIG_ASYNCSIG) + { + original_signals[sig] = SIG_DFL; /* XXX */ + set_signal_handler (sig, SIG_DFL); + change_signal (sig, (char *)DEFAULT_SIG); + return; + } + /* If we aren't trapping this signal, don't bother doing anything else. */ /* We special-case SIGCHLD and IMPOSSIBLE_TRAP_HANDLER (see above) as a sentinel to determine whether or not disposition is reset to the default |