summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2023-01-24 11:14:22 -0500
committerChet Ramey <chet.ramey@case.edu>2023-01-24 11:14:22 -0500
commitd0bc56a32584da615e5baff315d26ac7139a6ae2 (patch)
tree63bec3c93f76846a246528be6cf8f624da6d0ba6
parenta37b2af98533ace0ca90b3a2187481ee08e2615f (diff)
downloadbash-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.chlog24
-rw-r--r--CWRU/misc/sigs.c8
-rw-r--r--CWRU/misc/sigstat.c9
-rw-r--r--lib/readline/doc/rltech.texi2
-rw-r--r--lib/readline/doc/version.texi4
-rw-r--r--lib/readline/input.c66
-rw-r--r--lib/readline/rlprivate.h16
-rw-r--r--subst.c14
-rw-r--r--trap.c11
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
diff --git a/subst.c b/subst.c
index 92ca364c..e56284d4 100644
--- a/subst.c
+++ b/subst.c
@@ -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)
diff --git a/trap.c b/trap.c
index 2368e5b3..07e7ddec 100644
--- a/trap.c
+++ b/trap.c
@@ -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