bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch] unsafe signal handler


From: Tim Waugh
Subject: [patch] unsafe signal handler
Date: Wed, 7 Dec 2005 11:43:02 +0000
User-agent: Mutt/1.4.2.1i

Hi,

Here is a patch which aims to address the problem reported earlier:

  http://lists.gnu.org/archive/html/bug-bash/2005-07/msg00129.html

by making the signal handler set a flag which is then checked at
strategic points in the main flow of code.

What do you think?

Tim.
*/

--- bash-3.0/sig.c.sighandler   2005-12-06 16:55:26.000000000 +0000
+++ bash-3.0/sig.c      2005-12-06 17:14:29.000000000 +0000
@@ -58,6 +58,8 @@
 extern int loop_level, continuing, breaking;
 extern int parse_and_execute_level, shell_initialized;
 
+int need_termination_unwind_protect = 0;
+
 /* Non-zero after SIGINT. */
 int interrupt_state;
 
@@ -408,6 +410,13 @@
 termination_unwind_protect (sig)
      int sig;
 {
+  need_termination_unwind_protect = sig;
+  SIGRETURN (0);
+}
+
+void
+do_termination_unwind_protect (int sig)
+{
   if (sig == SIGINT && signal_is_trapped (SIGINT))
     run_interrupt_trap ();
 
@@ -429,8 +438,6 @@
   run_exit_trap ();
   set_signal_handler (sig, SIG_DFL);
   kill (getpid (), sig);
-
-  SIGRETURN (0);
 }
 
 /* What we really do when SIGINT occurs. */
--- bash-3.0/sig.h.sighandler   2005-12-06 17:00:22.000000000 +0000
+++ bash-3.0/sig.h      2005-12-06 17:17:32.000000000 +0000
@@ -109,8 +109,12 @@
 
 #endif /* JOB_CONTROL */
 
+/* Global variables from sig.c */
+extern int need_termination_unwind_protect;
+
 /* Functions from sig.c. */
 extern sighandler termination_unwind_protect __P((int));
+extern void do_termination_unwind_protect __P((int));
 extern sighandler sigint_sighandler __P((int));
 extern void initialize_signals __P((int));
 extern void initialize_terminating_signals __P((void));
@@ -123,4 +127,11 @@
 extern SigHandler *trap_to_sighandler __P((int));
 extern sighandler trap_handler __P((int));
 
+#define CATCH_SIGNALS()                                                        
\
+  do                                                                   \
+    {                                                                  \
+      if (need_termination_unwind_protect)                             \
+       do_termination_unwind_protect (need_termination_unwind_protect); \
+    } while (0)
+       
 #endif /* _SIG_H_ */
--- bash-3.0/input.c.sighandler 2005-12-06 17:19:59.000000000 +0000
+++ bash-3.0/input.c    2005-12-06 17:27:04.000000000 +0000
@@ -41,6 +41,7 @@
 #include "input.h"
 #include "error.h"
 #include "externs.h"
+#include "sig.h"
 
 #if !defined (errno)
 extern int errno;
@@ -66,6 +67,7 @@
     {
       while (1)
        {
+         CATCH_SIGNALS ();
          local_bufused = read (fileno (stream), localbuf, sizeof(localbuf));
          if (local_bufused > 0)
            break;
--- bash-3.0/jobs.c.sighandler  2005-12-06 17:22:46.000000000 +0000
+++ bash-3.0/jobs.c     2005-12-06 17:26:06.000000000 +0000
@@ -2513,6 +2513,7 @@
     retry:
       if (wcontinued_not_supported)
        waitpid_flags &= ~WCONTINUED;
+      CATCH_SIGNALS ();
       pid = WAITPID (-1, &status, waitpid_flags);
       if (pid == -1 && errno == EINVAL)
        {
@@ -2537,6 +2538,7 @@
 
       /* If waitpid returns 0, there are running children.  If it returns -1,
         the only other error POSIX says it can return is EINTR. */
+      CATCH_SIGNALS ();
       if (pid <= 0)
        continue;       /* jumps right to the test */
 
--- bash-3.0/execute_cmd.c.sighandler   2005-12-07 11:26:31.000000000 +0000
+++ bash-3.0/execute_cmd.c      2005-12-07 11:27:28.000000000 +0000
@@ -360,6 +360,7 @@
     unlink_fifo_list ();
 #endif /* PROCESS_SUBSTITUTION */
 
+  CATCH_SIGNALS ();
   return (result);
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]