0.pre7.9:
[sbcl.git] / src / runtime / interrupt.c
index 4dc22af..c516822 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <signal.h>
 #ifdef mach /* KLUDGE: #ifdef on lowercase symbols? Ick. -- WHN 19990904 */
@@ -213,6 +214,7 @@ undo_fake_foreign_function_call(os_context_t *context)
      * FREE_INTERRUPT_CONTEXT_INDEX? If so, we should say so. And
      * perhaps yes, unbind_to_here() really would be clearer and less
      * fragile.. */
+    /* dan (2001.08.10) thinks the above supposition is probably correct */
     unbind();
 
 #ifdef reg_ALLOC
@@ -592,18 +594,19 @@ uninstall_low_level_interrupt_handlers_atexit(void)
     }
 }
 
-/* Install a special low-level handler for signal; or if handler is
- * SIG_DFL, remove any special handling for signal.
+/* Undoably install a special low-level handler for signal; or if
+ * handler is SIG_DFL, remove any special handling for signal.
  *
- * The "undoably_" part is because we also arrange with atexit() for
- * the handler to be restored to its old value. This is for tidiness,
- * though it shouldn't really matter in normal operation of the
- * program, except perhaps that it removes a window when e.g. SIGINT
- * would be handled bizarrely. The original motivation was that some
- * memory corruption problems in OpenBSD ca sbcl-0.6.12.12 became
- * unnecessarily hard to debug when they ended up back in gencgc.c
- * code (courtesy of the gencgc SIGSEGV handler) after exit() was
- * called. */
+ * The "undoably" aspect is because we also arrange with atexit() for
+ * the handler to be restored to its old value. This is for tidiness:
+ * it shouldn't matter much ordinarily, but it does remove a window
+ * where e.g. memory fault signals (SIGSEGV or SIGBUS, which in
+ * ordinary operation of SBCL are sent to the generational garbage
+ * collector, then possibly onward to Lisp code) or SIGINT (which is
+ * ordinarily passed to Lisp code) could otherwise be handled
+ * bizarrely/brokenly because the Lisp code would try to deal with
+ * them using machinery (like stream output buffers) which has already
+ * been dismantled. */
 void
 undoably_install_low_level_interrupt_handler (int signal,
                                              void handler(int,
@@ -623,18 +626,19 @@ undoably_install_low_level_interrupt_handler (int signal,
     sigaddset_blockable(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO | SA_RESTART;
 
-    /* In the case of interrupt handlers which are modified
-     * more than once, we only save the original unmodified
-     * copy. */
+    /* In the case of interrupt handlers which are modified more than
+     * once, we only save the original unmodified copy. */
     if (!old_low_level_signal_handler_state->was_modified) {
+       struct sigaction *old_handler =
+           (struct sigaction*) &old_low_level_signal_handler_state->handler;
        old_low_level_signal_handler_state->was_modified = 1;
-       sigaction(signal, &sa, &old_low_level_signal_handler_state->handler);
+       sigaction(signal, &sa, old_handler);
     } else {
        sigaction(signal, &sa, NULL);
     }
 
     interrupt_low_level_handlers[signal] =
-       (ARE_SAME_HANDLER(handler,SIG_DFL) ? 0 : handler);
+       (ARE_SAME_HANDLER(handler, SIG_DFL) ? 0 : handler);
 }
 
 /* This is called from Lisp. */