+/*
+ * what low-level signal handlers looked like before
+ * undoably_install_low_level_interrupt_handler() got involved
+ */
+struct low_level_signal_handler_state {
+ int was_modified;
+ void (*handler)(int, siginfo_t*, void*);
+} old_low_level_signal_handler_states[NSIG];
+
+void
+uninstall_low_level_interrupt_handlers_atexit(void)
+{
+ int signal;
+ for (signal = 0; signal < NSIG; ++signal) {
+ struct low_level_signal_handler_state
+ *old_low_level_signal_handler_state =
+ old_low_level_signal_handler_states + signal;
+ if (old_low_level_signal_handler_state->was_modified) {
+ struct sigaction sa;
+ sa.sa_sigaction = old_low_level_signal_handler_state->handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO | SA_RESTART;
+ sigaction(signal, &sa, NULL);
+ }
+ }
+}
+
+/* Undoably install a special low-level handler for signal; or if
+ * handler is SIG_DFL, remove any special handling for signal.
+ *
+ * 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. */