From a237321b33a4455f3454ffb0adf99da3e128c7e0 Mon Sep 17 00:00:00 2001 From: Andreas Lundin Date: Tue, 19 Jul 2022 16:29:03 +0200 Subject: [PATCH] re-write SIGTERM handling Exit safely on SIGTERM by emitting "gui exit" from the main loops of fe-text and fe-none rather than from the signal handler itself. Based on feedback from Nei and dwfreed. --- src/common.h | 2 +- src/core/core.c | 17 +++++++++++++++-- src/core/core.h | 1 + src/core/settings.c | 14 -------------- src/fe-none/irssi.c | 12 ++++++++++-- src/fe-text/irssi.c | 5 +++++ 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/common.h b/src/common.h index 1d4fd207..e51c24db 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ -#define IRSSI_ABI_VERSION 49 +#define IRSSI_ABI_VERSION 50 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/core.c b/src/core/core.c index e9af84f7..5d72ca0a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -68,6 +68,7 @@ void wcwidth_wrapper_deinit(void); int irssi_gui; int irssi_init_finished; int sighup_received; +int sigterm_received; time_t client_start_time; static char *irssi_dir, *irssi_config_file; @@ -89,6 +90,11 @@ static void sig_hup(int signo) sighup_received = TRUE; } +static void sig_term(int signo) +{ + sigterm_received = TRUE; +} + static void read_settings(void) { static int signals[] = { @@ -113,8 +119,15 @@ static void read_settings(void) sigaction(SIGHUP, &act, NULL); for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) { - act.sa_handler = find_substr(ignores, signames[n]) ? - SIG_IGN : SIG_DFL; + if (find_substr(ignores, signames[n])) { + act.sa_handler = SIG_IGN; + } else { + /* set default handlers */ + if (signals[n] == SIGTERM) + act.sa_handler = sig_term; + else + act.sa_handler = SIG_DFL; + } sigaction(signals[n], &act, NULL); } diff --git a/src/core/core.h b/src/core/core.h index 3c544753..62c54b22 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -14,6 +14,7 @@ extern int irssi_gui; extern int irssi_init_finished; /* TRUE after "irssi init finished" signal is sent */ extern int sighup_received; /* TRUE after received SIGHUP. */ +extern int sigterm_received; /* TRUE after received SIGTERM. */ extern time_t client_start_time; void core_preinit(const char *path); diff --git a/src/core/settings.c b/src/core/settings.c index 1e7ef2ee..065c8fed 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -673,18 +673,6 @@ GSList *settings_get_sorted(void) return list; } -void sig_term(int n) -{ - /* if we get SIGTERM after this, just die instead of coming back here. */ - signal(SIGTERM, SIG_DFL); - - /* quit from all servers too.. */ - signal_emit("command quit", 1, ""); - - /* and die */ - raise(SIGTERM); -} - /* Yes, this is my own stupid checksum generator, some "real" algorithm would be nice but would just take more space without much real benefit */ static unsigned int file_checksum(const char *fname) @@ -805,8 +793,6 @@ static void init_configfile(void) signal_emit("gui dialog", 2, "error", str); g_free(str); } - - signal(SIGTERM, sig_term); } int settings_reread(const char *fname) diff --git a/src/fe-none/irssi.c b/src/fe-none/irssi.c index f2724443..c442bd7f 100644 --- a/src/fe-none/irssi.c +++ b/src/fe-none/irssi.c @@ -29,10 +29,11 @@ static GMainLoop *main_loop; static char *autoload_module; static int reload; +static int quitting; static void sig_exit(void) { - g_main_loop_quit(main_loop); + quitting = TRUE; } static void sig_reload(void) @@ -103,7 +104,14 @@ int main(int argc, char **argv) reload = FALSE; module_load(autoload_module, NULL); main_loop = g_main_loop_new(NULL, TRUE); - g_main_loop_run(main_loop); + while (!quitting && !reload) { + if (sigterm_received) { + sigterm_received = FALSE; + signal_emit("gui exit", 0); + } + + g_main_context_iteration(NULL, TRUE); + } g_main_loop_unref(main_loop); } while (reload); diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 76bc5dfd..9952f748 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -331,6 +331,11 @@ int main(int argc, char **argv) /* Does the same as g_main_run(main_loop), except we can call our dirty-checker after each iteration */ while (!quitting) { + if (sigterm_received) { + sigterm_received = FALSE; + signal_emit("gui exit", 0); + } + if (sighup_received) { sighup_received = FALSE;