]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
allow async ignored signals to be reset to SIG_DFL; give rl_input_available_hook...
authorChet Ramey <chet.ramey@case.edu>
Tue, 24 Jan 2023 16:14:22 +0000 (11:14 -0500)
committerChet Ramey <chet.ramey@case.edu>
Tue, 24 Jan 2023 16:14:22 +0000 (11:14 -0500)
CWRU/CWRU.chlog
CWRU/misc/sigs.c
CWRU/misc/sigstat.c
lib/readline/doc/rltech.texi
lib/readline/doc/version.texi
lib/readline/input.c
lib/readline/rlprivate.h
subst.c
trap.c

index ebf5eafea42ba78509b154892e02cd4e0f6342e8..6e029e1c8d3e16eafbbc65bfd4c7cdffe626a6cc 100644 (file)
@@ -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
index bae93f8adc2d56d645b91f71277f4e759f87b1e4..c575de90f5848aa786e4643efd0ba2cf4ac7ce65 100644 (file)
 
 #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++) {
index 9135baa4aee8502fc74b27b0530f877076900376..41ed361e156e340531a76a377cf6de746a108959 100644 (file)
 #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;
index a93f77dabf81de0d9575aaf0947747f3f0bc96d5..f40bc2bd552691a5e5cf7d8e1de1e8a230a2e048 100644 (file)
@@ -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.
index 0d4af12e68e394dbcba178cf847eb144dc10bef6..2b80d343b9b9d4e9dfdeeafe2d115031289201c7 100644 (file)
@@ -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
index 186e0fac7415cb821f6f7c73319f31795fdb8598..229474fff6dcca8efa6de670780d862267149a07 100644 (file)
@@ -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)
 {
index 15a75c5bb28bf1dcb8d028eb1e00596e6293f448..77a4d8c6ca8ca80a58daa01d86f16fca576dee1c 100644 (file)
@@ -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 92ca364c599efb9515d808d2b5a6a332850ba7ed..e56284d4ff395f384b0060a6acc3089f3aaddbde 100644 (file)
--- 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 2368e5b3750059e48c841c25a9025c06f393c71b..07e7ddecfd24be0633338c5860e063262db8b8f1 100644 (file)
--- 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