Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarSignalHandler_unix.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarSignalHandler_unix.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarSignalHandler_unix.cpp')
-rw-r--r--source/core/StarSignalHandler_unix.cpp92
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;
+}
+
+}