#ifndef ULE_SIGNAL_HANDLER_H #define ULE_SIGNAL_HANDLER_H #include // for signal() and the SIG macros #include "config.h" #include "types.h" #include "print.h" // the running process can receive and respond to a variety of platform-dependent 'signals' during runtime from the OS. // freebsd has something like 30 signals, windows has a subset, just 6. we'll just deal with 6. static inline void defaultHandler(s32 signal) { ULE_TYPES_H_FTAG; switch (signal) { case SIGSEGV: case SIGABRT: print("%serror%s: %d\n", ANSI_RED, ANSI_RESET, signal); trace(); case SIGINT: die("Bye! (SIGINT)\n"); case SIGTERM: die(" We were asked to stop (SIGTERM).\n"); case SIGFPE: die(" (SIGFPE).\n"); case SIGILL: die(" (SIGILL).\n"); default: die(" unknown/non-standard signal raised: %d\n", signal); break; } } static void setSignalHandlers(void(*handler)(s32 signal) = defaultHandler) { ULE_TYPES_H_FTAG; if (signal(SIGSEGV, handler) == SIG_ERR) die("failed to set SIGSEGV handler... zzz...\n"); if (signal(SIGABRT, handler) == SIG_ERR) die("failed to set SIGABRT handler... zzz...\n"); if (signal(SIGFPE, handler) == SIG_ERR) die("failed to set SIGFPE handler... zzz...\n"); if (signal(SIGILL, handler) == SIG_ERR) die("failed to set SIGILL handler... zzz...\n"); // does this fire on using sprintf (on Catalina)? if (signal(SIGINT, handler) == SIG_ERR) die("failed to set SIGINT handler... zzz...\n"); if (signal(SIGTERM, handler) == SIG_ERR) die("failed to set SIGTERM handler... zzz...\n"); } #endif