diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarSignalHandler_unix.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarSignalHandler_unix.cpp')
-rw-r--r-- | source/core/StarSignalHandler_unix.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/source/core/StarSignalHandler_unix.cpp b/source/core/StarSignalHandler_unix.cpp new file mode 100644 index 0000000..df8114a --- /dev/null +++ b/source/core/StarSignalHandler_unix.cpp @@ -0,0 +1,92 @@ +#include "StarSignalHandler.hpp" + +#include <signal.h> + +namespace Star { + +struct SignalHandlerImpl { + bool handlingFatal; + bool handlingInterrupt; + bool interrupted; + + SignalHandlerImpl() : handlingFatal(false), handlingInterrupt(false), interrupted(false) {} + + ~SignalHandlerImpl() { + setHandleFatal(false); + setHandleInterrupt(false); + } + + void setHandleFatal(bool b) { + handlingFatal = b; + if (handlingFatal) { + signal(SIGSEGV, handleFatal); + signal(SIGILL, handleFatal); + signal(SIGFPE, handleFatal); + signal(SIGBUS, handleFatal); + } else { + signal(SIGSEGV, SIG_DFL); + signal(SIGILL, SIG_DFL); + signal(SIGFPE, SIG_DFL); + signal(SIGBUS, SIG_DFL); + } + } + + void setHandleInterrupt(bool b) { + handlingInterrupt = b; + if (handlingInterrupt) + signal(SIGINT, handleInterrupt); + else + signal(SIGINT, SIG_DFL); + } + + static void handleFatal(int signum) { + if (signum == SIGSEGV) + fatalError("Segfault Encountered!", true); + else if (signum == SIGILL) + fatalError("Illegal Instruction Encountered!", true); + else if (signum == SIGFPE) + fatalError("Floating Point Exception Encountered!", true); + else if (signum == SIGBUS) + fatalError("Bus Error Encountered!", true); + } + + static void handleInterrupt(int) { + if (SignalHandler::s_singleton) + SignalHandler::s_singleton->interrupted = true; + } +}; + +SignalHandlerImplUPtr SignalHandler::s_singleton; + +SignalHandler::SignalHandler() { + if (s_singleton) + throw StarException("Singleton SignalHandler has been constructed twice!"); + + s_singleton = make_unique<SignalHandlerImpl>(); +} + +SignalHandler::~SignalHandler() { + s_singleton.reset(); +} + +void SignalHandler::setHandleFatal(bool handleFatal) { + s_singleton->setHandleFatal(handleFatal); +} + +bool SignalHandler::handlingFatal() const { + return s_singleton->handlingFatal; +} + +void SignalHandler::setHandleInterrupt(bool handleInterrupt) { + s_singleton->setHandleInterrupt(handleInterrupt); +} + +bool SignalHandler::handlingInterrupt() const { + return s_singleton->handlingInterrupt; +} + +bool SignalHandler::interruptCaught() const { + return s_singleton->interrupted; +} + +} |