From eda6f292f952a842ec5543e4f4e79d9af2373e30 Mon Sep 17 00:00:00 2001 From: themuffinator Date: Fri, 21 Nov 2025 17:15:22 +0000 Subject: [PATCH] Use sigaction for signal setup --- src/unix/system.cpp | 84 ++++++++++++++++++++++++++++----------------- src/unix/tty.cpp | 19 ++++++++-- 2 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/unix/system.cpp b/src/unix/system.cpp index 2620e4a..24b653a 100644 --- a/src/unix/system.cpp +++ b/src/unix/system.cpp @@ -204,6 +204,25 @@ static void term_handler(int signum) terminate_flag = signum; } +/* +================= +Sys_SetSignalHandler + +Configures a signal handler using sigaction. +Returns true on success. +================= +*/ +static bool Sys_SetSignalHandler(int signum, void (*handler)(int), int flags) +{ + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_handler = handler; + sa.sa_flags = flags; + + return sigaction(signum, &sa, NULL) == 0; +} + /* ================= Sys_Init @@ -211,41 +230,42 @@ Sys_Init */ void Sys_Init(void) { - const char *homedir; - - signal(SIGTERM, term_handler); - signal(SIGINT, term_handler); - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, term_handler); - signal(SIGUSR1, usr1_handler); - - // basedir - // allows the game to run from outside the data tree - sys_basedir = Cvar_Get("basedir", DATADIR, CVAR_NOSET); - - // homedir - // specifies per-user writable directory for demos, screenshots, etc - if (HOMEDIR[0] == '~') { - char *s = getenv("HOME"); - if (s && strlen(s) >= MAX_OSPATH - MAX_QPATH) - Sys_Error("HOME path too long"); - if (s && *s) { - homedir = va("%s%s", s, &HOMEDIR[1]); - } else { - homedir = ""; - } - } else { - homedir = HOMEDIR; - } + const char *homedir; + + if (!Sys_SetSignalHandler(SIGTERM, term_handler, 0) || + !Sys_SetSignalHandler(SIGINT, term_handler, 0) || + !Sys_SetSignalHandler(SIGTTIN, SIG_IGN, 0) || + !Sys_SetSignalHandler(SIGTTOU, SIG_IGN, 0) || + !Sys_SetSignalHandler(SIGPIPE, SIG_IGN, 0) || + !Sys_SetSignalHandler(SIGHUP, term_handler, 0) || + !Sys_SetSignalHandler(SIGUSR1, usr1_handler, SA_RESTART)) { + Sys_Error("Failed to install signal handlers"); + } - sys_homedir = Cvar_Get("homedir", homedir, CVAR_NOSET); - sys_libdir = Cvar_Get("libdir", LIBDIR, CVAR_NOSET); + // basedir + // allows the game to run from outside the data tree + sys_basedir = Cvar_Get("basedir", DATADIR, CVAR_NOSET); + + // homedir + // specifies per-user writable directory for demos, screenshots, etc + if (HOMEDIR[0] == '~') { + char *s = getenv("HOME"); + if (s && strlen(s) >= MAX_OSPATH - MAX_QPATH) + Sys_Error("HOME path too long"); + if (s && *s) { + homedir = va("%s%s", s, &HOMEDIR[1]); + } else { + homedir = ""; + } + } else { + homedir = HOMEDIR; + } - tty_init_input(); -} + sys_homedir = Cvar_Get("homedir", homedir, CVAR_NOSET); + sys_libdir = Cvar_Get("libdir", LIBDIR, CVAR_NOSET); + tty_init_input(); +} /* ================= Sys_Error diff --git a/src/unix/tty.cpp b/src/unix/tty.cpp index e3c2311..8091a2d 100644 --- a/src/unix/tty.cpp +++ b/src/unix/tty.cpp @@ -518,10 +518,18 @@ static void tty_parse_input(const char *text) } } +/* +============= +winch_handler + +Forces a refresh of the visible input line on terminal resize. +============= +*/ #ifdef TIOCGWINSZ static void winch_handler(int signum) { - tty_prompt.inputLine.visibleChars = 0; // force refresh + (void)signum; + tty_prompt.inputLine.visibleChars = 0; // force refresh } #endif @@ -567,7 +575,14 @@ void tty_init_input(void) goto no_tty; #ifdef TIOCGWINSZ - signal(SIGWINCH, winch_handler); + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_handler = winch_handler; + sa.sa_flags = SA_RESTART; + + if (sigaction(SIGWINCH, &sa, NULL) != 0) + goto no_tty; #endif // determine terminal width