1
0
Fork 0

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.
This commit is contained in:
Andreas Lundin 2022-07-19 16:29:03 +02:00
parent 722d3c4c3d
commit a237321b33
6 changed files with 32 additions and 19 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;