116 lines
1.9 KiB
C
116 lines
1.9 KiB
C
#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);
|
|
}
|