#include "handle.h" #include <assert.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> static void (*handler) (int); static volatile int caught_signal; static volatile bool handler_set; #define SIGNALS \ SIGNAL(SIGABRT) \ SIGNAL(SIGBUS) \ SIGNAL(SIGINT) \ SIGNAL(SIGSEGV) \ SIGNAL(SIGTERM) // *INDENT-OFF* #define SIGNAL(SIG) \ static void (*SIG ## _handler)(int); SIGNALS #undef SIGNAL const char * kissat_signal_name (int sig) { #define SIGNAL(SIG) \ if (sig == SIG) return #SIG; SIGNALS #undef SIGNAL if (sig == SIGALRM) return "SIGALRM"; return "SIGUNKNOWN"; } void kissat_reset_signal_handler (void) { if (!handler_set) return; #define SIGNAL(SIG) \ signal (SIG, SIG ## _handler); SIGNALS #undef SIGNAL handler_set = false; handler = 0; } // *INDENT-ON* static void catch_signal (int sig) { if (caught_signal) return; caught_signal = sig; assert (handler_set); assert (handler); handler (sig); kissat_reset_signal_handler (); raise (sig); } void kissat_init_signal_handler (void (*h) (int sig)) { assert (!handler); handler = h; handler_set = true; #define SIGNAL(SIG) \ SIG ##_handler = signal (SIG, catch_signal); SIGNALS #undef SIGNAL } static volatile bool caught_alarm; static volatile bool alarm_handler_set; static void (*SIGALRM_handler) (int); static void (*handle_alarm) (); static void catch_alarm (int sig) { assert (sig == SIGALRM); if (caught_alarm) return; if (!alarm_handler_set) raise (sig); assert (handle_alarm); caught_alarm = true; handle_alarm (); } void kissat_init_alarm (void (*handler) (void)) { assert (handler); assert (!caught_alarm); handle_alarm = handler; alarm_handler_set = true; assert (!SIGALRM_handler); SIGALRM_handler = signal (SIGALRM, catch_alarm); } void kissat_reset_alarm (void) { assert (alarm_handler_set); assert (handle_alarm); alarm_handler_set = false; handle_alarm = 0; (void) signal (SIGALRM, SIGALRM_handler); }