diff --git a/stepmania/src/archutils/Unix/SignalHandler.cpp b/stepmania/src/archutils/Unix/SignalHandler.cpp new file mode 100644 index 0000000000..da3dbc2f86 --- /dev/null +++ b/stepmania/src/archutils/Unix/SignalHandler.cpp @@ -0,0 +1,76 @@ +#include "global.h" + +#include "RageLog.h" +#include "SignalHandler.h" + +#include + +static vector handlers; +SaveSignals *saved_sigs; +static bool initted = false; + +static int signals[] = { + SIGALRM, SIGBUS, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGIOT, SIGPIPE, + SIGPWR, SIGQUIT, SIGSEGV, SIGTRAP, SIGTERM, SIGVTALRM, SIGXCPU, SIGXFSZ, + -1 +}; + +/* + * Store signals and restore them. This lets us clean up after libraries + * that like to mess with our signal handler. (Of course, if we undo + * signal handlers for libraries, we need to be sure to handle whatever it + * was cleaning up by hand.) + */ + +SaveSignals::SaveSignals() +{ + /* Store the old signal handlers. */ + for(int i = 0; signals[i] != -1; ++i) + { + old_handlers.push_back(); + sigaction(signals[i], NULL, &old_handlers.back()); + } +} + +SaveSignals::~SaveSignals() +{ + /* Restore the old signal handlers. */ + for(unsigned i = 0; i < old_handlers.size(); ++i) + sigaction(signals[i], &old_handlers[i], NULL); +} + +static void SigHandler(int sig) +{ + LOG->Trace("got sig %i", sig); + for(unsigned i = 0; i < handlers.size(); ++i) + handlers[i](sig); + + _exit(1); +} + +/* Hook up events to fatal signals, so we can clean up if we're killed. */ +void SignalHandler::OnClose(handler h) +{ + if(saved_sigs == NULL) + { + saved_sigs = new SaveSignals; + + /* Set up our signal handlers. */ + for(int i = 0; signals[i] != -1; ++i) + { + struct sigaction sa; + + sa.sa_handler = SigHandler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + + sigaction(signals[i], &sa, NULL); + } + } + handlers.push_back(h); +} + + +/* Written by Glenn Myanard. Public domain, copyrighting a simple signal handler + * is dumb. */ + diff --git a/stepmania/src/archutils/Unix/SignalHandler.h b/stepmania/src/archutils/Unix/SignalHandler.h new file mode 100644 index 0000000000..a64d40d339 --- /dev/null +++ b/stepmania/src/archutils/Unix/SignalHandler.h @@ -0,0 +1,25 @@ +#ifndef SIGNAL_HANDLER_H +#define SIGNAL_HANDLER_H + +#include + +class SaveSignals +{ + vector old_handlers; + +public: + SaveSignals(); /* save signals */ + ~SaveSignals(); /* restore signals */ +}; + +namespace SignalHandler +{ + typedef void (*handler)(int); + + void OnClose(handler); +}; + +#endif + +/* Written by Glenn Maynard. Public domain. */ +