From e4b9493ae4923595ec3ca67f85322129fb3056cf Mon Sep 17 00:00:00 2001
From: Chet Ramey <chet.ramey@case.edu>
Date: Mon, 30 Oct 2023 12:16:07 -0400
Subject: [PATCH] changes to SIGINT handler while waiting for a child; skip
 vertical whitespace after translating an integer

Upstream-Status: Backport from
[https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=fe24a6a55e8850298b496c5b9d82f1866eba190e]

[Adjust and drop some codes to be applicable the tree]

Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
 general.c         |  5 +++--
 jobs.c            | 24 ++++++++++++++++--------
 tests/redir.right |  4 ++--
 tests/redir11.sub |  2 ++
 tests/type.right  | 16 ++++++++--------
 tests/type.tests  | 24 ++++++++++++------------
 6 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/general.c b/general.c
index bda39f4..94a5339 100644
--- a/general.c
+++ b/general.c
@@ -264,8 +264,9 @@ legal_number (string, result)
   if (errno || ep == string)
     return 0;	/* errno is set on overflow or underflow */
 
-  /* Skip any trailing whitespace, since strtoimax does not. */
-  while (whitespace (*ep))
+  /* Skip any trailing whitespace, since strtoimax does not, using the same
+     test that strtoimax uses for leading whitespace. */
+  while (isspace ((unsigned char) *ep))
     ep++;
 
   /* If *string is not '\0' but *ep is '\0' on return, the entire string
diff --git a/jobs.c b/jobs.c
index d3e4ab0..903cf9c 100644
--- a/jobs.c
+++ b/jobs.c
@@ -2718,6 +2718,10 @@ wait_for_background_pids (ps)
 #define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids
 static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER;
 
+/* The current SIGINT handler as set by restore_sigint_handler. Only valid
+   immediately after restore_sigint_handler, used for continuations. */
+static SigHandler *cur_sigint_handler = INVALID_SIGNAL_HANDLER;   
+
 static int wait_sigint_received;
 static int child_caught_sigint;
 
@@ -2735,6 +2739,7 @@ wait_sigint_cleanup ()
 static void
 restore_sigint_handler ()
 {
+  cur_sigint_handler = old_sigint_handler;
   if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
     {
       set_signal_handler (SIGINT, old_sigint_handler);
@@ -2758,8 +2763,7 @@ wait_sigint_handler (sig)
       restore_sigint_handler ();
       /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
 	 what POSIX.2 says (see builtins/wait.def for more info). */
-      if (this_shell_builtin && this_shell_builtin == wait_builtin &&
-	  signal_is_trapped (SIGINT) &&
+      if (signal_is_trapped (SIGINT) &&
 	  ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler))
 	{
 	  trap_handler (SIGINT);	/* set pending_traps[SIGINT] */
@@ -2782,6 +2786,8 @@ wait_sigint_handler (sig)
     {
       set_exit_status (128+SIGINT);
       restore_sigint_handler ();
+      if (cur_sigint_handler == INVALID_SIGNAL_HANDLER)
+	set_sigint_handler ();		/* XXX - only do this in one place */
       kill (getpid (), SIGINT);
     }
 
@@ -2926,11 +2932,13 @@ wait_for (pid, flags)
     {
       SigHandler *temp_sigint_handler;
 
-      temp_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
-      if (temp_sigint_handler == wait_sigint_handler)
-	internal_debug ("wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = %d", running_trap);
-      else
-	old_sigint_handler = temp_sigint_handler;
+      temp_sigint_handler = old_sigint_handler;
+      old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
+      if (old_sigint_handler == wait_sigint_handler)
+	{
+	  internal_debug ("wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = %d", running_trap);
+	  old_sigint_handler = temp_sigint_handler;
+	}
       waiting_for_child = 0;
       if (old_sigint_handler == SIG_IGN)
 	set_signal_handler (SIGINT, old_sigint_handler);
@@ -4141,7 +4149,7 @@ set_job_status_and_cleanup (job)
 		 SIGINT (if we reset the sighandler to the default).
 		 In this case, we have to fix things up.  What a crock. */
 	      if (temp_handler == trap_handler && signal_is_trapped (SIGINT) == 0)
-		  temp_handler = trap_to_sighandler (SIGINT);
+		temp_handler = trap_to_sighandler (SIGINT);
 	      restore_sigint_handler ();
 	      if (temp_handler == SIG_DFL)
 		termsig_handler (SIGINT);	/* XXX */
diff --git a/tests/redir.right b/tests/redir.right
index 8db1041..9e1403c 100644
--- a/tests/redir.right
+++ b/tests/redir.right
@@ -154,10 +154,10 @@ foo
 1
 7
 after: 42
-./redir11.sub: line 53: $(ss= declare -i ss): ambiguous redirect
+./redir11.sub: line 55: $(ss= declare -i ss): ambiguous redirect
 after: 42
 a+=3
 foo
 foo
-./redir11.sub: line 75: 42: No such file or directory
+./redir11.sub: line 77: 42: No such file or directory
 42
diff --git a/tests/redir11.sub b/tests/redir11.sub
index d417cdb..ca9854c 100644
--- a/tests/redir11.sub
+++ b/tests/redir11.sub
@@ -34,6 +34,8 @@ a=4 b=7 ss=4 declare -i ss
 a=4 b=7 foo
 echo after: $a
 
+exec 7>&- 4>&-
+
 unset a
 a=4 echo foo 2>&1 >&$(foo) | { grep -q 'Bad file' || echo 'redir11 bad 3'; }
 a=1 echo foo 2>&1 >&$(foo) | { grep -q 'Bad file' || echo 'redir11 bad 4'; }
diff --git a/tests/type.right b/tests/type.right
index bbc228e..c0c1c8b 100644
--- a/tests/type.right
+++ b/tests/type.right
@@ -24,15 +24,15 @@ func ()
 }
 while
 while is a shell keyword
-./type.tests: line 56: type: m: not found
-alias m='more'
-alias m='more'
-m is aliased to `more'
+./type.tests: line 56: type: morealias: not found
+alias morealias='more'
+alias morealias='more'
+morealias is aliased to `more'
 alias
-alias m='more'
-alias m='more'
-alias m='more'
-m is aliased to `more'
+alias morealias='more'
+alias morealias='more'
+alias morealias='more'
+morealias is aliased to `more'
 builtin
 builtin is a shell builtin
 /bin/sh
diff --git a/tests/type.tests b/tests/type.tests
index fd39c18..ddc1540 100644
--- a/tests/type.tests
+++ b/tests/type.tests
@@ -25,8 +25,6 @@ type -r ${THIS_SH}
 type notthere
 command -v notthere
 
-alias m=more
-
 unset -f func 2>/dev/null
 func() { echo this is func; }
 
@@ -49,24 +47,26 @@ command -V func
 command -v while
 command -V while
 
+alias morealias=more
+
 # the following two lines should produce the same output
 # post-3.0 patch makes command -v silent, as posix specifies
 # first test with alias expansion off (should all fail or produce no output)
-type -t m
-type m
-command -v m
+type -t morealias
+type morealias
+command -v morealias
 alias -p
-alias m
+alias morealias
 
 # then test with alias expansion on 
 shopt -s expand_aliases
-type m
-type -t m
-command -v m
+type morealias
+type -t morealias
+command -v morealias
 alias -p
-alias m
+alias morealias
 
-command -V m
+command -V morealias
 shopt -u expand_aliases
 
 command -v builtin
@@ -76,7 +76,7 @@ command -V /bin/sh
 
 unset -f func
 type func
-unalias m
+unalias morealias
 type m
 
 hash -r
