summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2016-11-13 16:07:24 +0100
committerSébastien Helleu <flashcode@flashtux.org>2016-11-13 16:07:24 +0100
commit018b9693812eb58e6d15602366c61e937a9ea930 (patch)
tree9511933abc8df58c81c50b3a23996775e2529ecc /src/gui
parent01f84430738b2a3e3987addc1a80197fcd078ba1 (diff)
downloadweechat-018b9693812eb58e6d15602366c61e937a9ea930.zip
core: fix deadlock when quitting after a signal is received (closes #32)
The code in signal handers (SIGHUP, SIGQUIT, SIGTERM) is moved into main loop, this hopefully fixes the deadlock when quitting after receiving one of these signals. The code in SIGWINCH signal handler is moved too (even if it shouldn't be a problem).
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/curses/gui-curses-key.c9
-rw-r--r--src/gui/curses/gui-curses-main.c53
2 files changed, 57 insertions, 5 deletions
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c
index cd267064a..6529510f3 100644
--- a/src/gui/curses/gui-curses-key.c
+++ b/src/gui/curses/gui-curses-key.c
@@ -525,9 +525,12 @@ gui_key_read_cb (const void *pointer, void *data, int fd)
if (ret == 0)
{
/* no data on stdin, terminal lost */
- log_printf (_("Terminal lost, exiting WeeChat..."));
- (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
- weechat_quit = 1;
+ if (!weechat_quit)
+ {
+ log_printf (_("Terminal lost, exiting WeeChat..."));
+ (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
+ weechat_quit = 1;
+ }
return WEECHAT_RC_OK;
}
if (ret < 0)
diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c
index 8407f8c63..bcc32c38a 100644
--- a/src/gui/curses/gui-curses-main.c
+++ b/src/gui/curses/gui-curses-main.c
@@ -60,7 +60,8 @@
#include "gui-curses.h"
-int gui_signal_sigwinch_received = 0; /* sigwinch signal (term resized) */
+volatile sig_atomic_t gui_signal_sigwinch_received = 0; /* sigwinch signal */
+ /* (terminal has been resized) */
int gui_term_cols = 0; /* number of columns in terminal */
int gui_term_lines = 0; /* number of lines in terminal */
@@ -249,8 +250,51 @@ void
gui_main_signal_sigwinch ()
{
gui_signal_sigwinch_received = 1;
+}
+
+/*
+ * Callback for signals received that will make WeeChat quit.
+ */
+
+void
+gui_main_handle_quit_signals ()
+{
+ char str_signal[64], str_weechat_signal[64];
+ int rc;
+
+ switch (weechat_quit_signal)
+ {
+ case SIGHUP:
+ snprintf (str_signal, sizeof(str_signal), "SIGHUP");
+ break;
+ case SIGQUIT:
+ snprintf (str_signal, sizeof(str_signal), "SIGQUIT");
+ break;
+ case SIGTERM:
+ snprintf (str_signal, sizeof(str_signal), "SIGTERM");
+ break;
+ default:
+ str_signal[0] = '\0';
+ break;
+ }
+
+ if (str_signal[0])
+ {
+ snprintf (str_weechat_signal, sizeof(str_weechat_signal),
+ "signal_%s", str_signal);
+ string_tolower(str_weechat_signal);
+ rc = hook_signal_send (str_weechat_signal,
+ WEECHAT_HOOK_SIGNAL_STRING, NULL);
+ if ((rc != WEECHAT_RC_OK_EAT) && !weechat_quit)
+ {
+ log_printf (_("Signal %s received, exiting WeeChat..."),
+ str_signal);
+ (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
+ weechat_quit = 1;
+ }
+ }
- gui_window_ask_refresh (2);
+ weechat_quit_signal = 0;
}
/*
@@ -416,6 +460,7 @@ gui_main_loop ()
(void) hook_signal_send ("signal_sigwinch",
WEECHAT_HOOK_SIGNAL_STRING, NULL);
gui_signal_sigwinch_received = 0;
+ gui_window_ask_refresh (2);
}
gui_color_pairs_auto_reset_pending = 0;
@@ -425,6 +470,10 @@ gui_main_loop ()
/* run process (with fork) */
hook_process_exec ();
+
+ /* handle signals received */
+ if (weechat_quit_signal > 0)
+ gui_main_handle_quit_signals ();
}
/* remove keyboard hook */