#include <csignal>
#ifdef __linux__
#include <sys/prctl.h>
#endif
#include "Debug/Tracer.hpp"
#include "Shell/Options.hpp"
#include "Shell/Statistics.hpp"
#include "Shell/UIHelper.hpp"
#include "Environment.hpp"
#include "System.hpp"
namespace Lib {
const char* signalToString (int sigNum)
{
switch (sigNum)
{
case SIGTERM:
return "SIGTERM";
# ifndef _MSC_VER
case SIGQUIT:
return "SIGQUIT";
case SIGHUP:
return "SIGHUP";
case SIGXCPU:
return "SIGXCPU";
case SIGBUS:
return "SIGBUS";
case SIGTRAP:
return "SIGTRAP";
# endif
case SIGINT:
return "SIGINT";
case SIGILL:
return "SIGILL";
case SIGFPE:
return "SIGFPE";
case SIGSEGV:
return "SIGSEGV";
case SIGABRT:
return "SIGABRT";
default:
return "UNKNOWN SIGNAL";
}
}
static std::sig_atomic_t TERMINAL_SIGNAL_HANDLED = false;
void handleSignal (int sigNum)
{
if(TERMINAL_SIGNAL_HANDLED)
return;
switch(sigNum) {
case SIGINT:
case SIGTERM:
#ifndef _MSC_VER
case SIGHUP:
case SIGXCPU:
#endif
TERMINAL_SIGNAL_HANDLED = true;
System::terminateImmediately(VAMP_RESULT_STATUS_INTERRUPTED);
case SIGABRT:
case SIGFPE:
case SIGILL:
case SIGSEGV:
#ifndef _MSC_VER
case SIGQUIT:
case SIGBUS:
#endif
TERMINAL_SIGNAL_HANDLED = true;
Shell::reportSpiderFail();
if(Shell::outputAllowed(true)) {
Shell::addCommentSignForSZS(std::cout);
std::cout << "Aborted by signal " << signalToString(sigNum);
if(env.options)
std::cout << " on " << env.options->inputFile();
std::cout << std::endl;
if (!Shell::UIHelper::portfolioParent) {
if(env.statistics)
env.statistics->print(std::cout);
Debug::Tracer::printStack();
}
System::terminateImmediately(VAMP_RESULT_STATUS_OTHER_SIGNAL);
}
default:
break;
}
}
void System::setSignalHandlers()
{
signal(SIGTERM,handleSignal);
signal(SIGINT,handleSignal);
signal(SIGILL,handleSignal);
signal(SIGFPE,handleSignal);
signal(SIGSEGV,handleSignal);
signal(SIGABRT,handleSignal);
#ifndef _MSC_VER
signal(SIGQUIT,handleSignal);
signal(SIGHUP,handleSignal);
signal(SIGXCPU,handleSignal);
signal(SIGBUS,handleSignal);
signal(SIGTRAP,handleSignal);
#endif
}
void System::registerForSIGHUPOnParentDeath()
{
#ifdef __linux__
prctl(PR_SET_PDEATHSIG, SIGHUP);
#endif
}
};