2023-03-26 19:15:17 +08:00

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);
}