#include "unittest.h"
#ifdef _WIN32
static struct sigaction Sigactions[NSIG];
static LONG CALLBACK
exception_handler(_In_ PEXCEPTION_POINTERS ExceptionInfo)
{
DWORD excode = ExceptionInfo->ExceptionRecord->ExceptionCode;
if (excode == EXCEPTION_ACCESS_VIOLATION)
Sigactions[SIGSEGV].sa_handler(SIGSEGV);
return EXCEPTION_CONTINUE_EXECUTION;
}
static void
signal_handler_wrapper(int signum)
{
_crt_signal_t retval = signal(signum, signal_handler_wrapper);
if (retval == SIG_ERR)
UT_FATAL("!signal: %d", signum);
if (Sigactions[signum].sa_handler)
Sigactions[signum].sa_handler(signum);
else
UT_FATAL("handler for signal: %d is not defined", signum);
}
#endif
int
ut_sigaction(const char *file, int line, const char *func,
int signum, struct sigaction *act, struct sigaction *oldact)
{
#ifndef _WIN32
int retval = sigaction(signum, act, oldact);
if (retval != 0)
ut_fatal(file, line, func, "!sigaction: %s",
os_strsignal(signum));
return retval;
#else
UT_ASSERT(signum < NSIG);
os_mutex_lock(&Sigactions_lock);
if (oldact)
*oldact = Sigactions[signum];
if (act)
Sigactions[signum] = *act;
os_mutex_unlock(&Sigactions_lock);
if (signum == SIGABRT) {
ut_suppress_errmsg();
}
if (signum == SIGSEGV) {
AddVectoredExceptionHandler(0, exception_handler);
}
_crt_signal_t retval = signal(signum, signal_handler_wrapper);
if (retval == SIG_ERR)
ut_fatal(file, line, func, "!signal: %d", signum);
if (oldact != NULL)
oldact->sa_handler = retval;
return 0;
#endif
}