summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2021-03-16 18:47:31 +0100
committerSébastien Helleu <flashcode@flashtux.org>2021-03-16 18:47:31 +0100
commit0dc7fbcb0ce6a13427c3c362d777554ec55ec74a (patch)
treefdee3f8c05be225d32d28db6597710c8acb3e09c /src
parentbb41de8c0255887720f570e5f0594a497f9ea0a0 (diff)
downloadweechat-0dc7fbcb0ce6a13427c3c362d777554ec55ec74a.zip
core: add options to customize commands on system signals, quit by default on SIGHUP when not running headless (closes #1595)
New options to customize behavior on signals received, with the default behavior: - weechat.signal.sighup: quit in normal mode, reload config in headless - weechat.signal.sigquit: quit - weechat.signal.sigterm: quit - weechat.signal.sigusr1: no command executed by default - weechat.signal.sigusr2: no command executed by default The signals SIGUSR1 and SIGUSR2 are introduced by this commit, so it's now possible to run commands when they are received. The SIGHUP signal makes now WeeChat quit, it was the behavior before version 2.9 of WeeChat (see commit de1e61f7cd50cbd1a99777fe6611642a51abf5f6).
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/Makefile.am2
-rw-r--r--src/core/hook/wee-hook-fd.c1
-rw-r--r--src/core/wee-command.c22
-rw-r--r--src/core/wee-command.h1
-rw-r--r--src/core/wee-config.c65
-rw-r--r--src/core/wee-config.h6
-rw-r--r--src/core/wee-debug.c2
-rw-r--r--src/core/wee-debug.h2
-rw-r--r--src/core/wee-hook.c4
-rw-r--r--src/core/wee-signal.c314
-rw-r--r--src/core/wee-signal.h37
-rw-r--r--src/core/wee-util.c72
-rw-r--r--src/core/wee-util.h13
-rw-r--r--src/core/weechat.c42
-rw-r--r--src/core/weechat.h2
-rw-r--r--src/gui/curses/gui-curses-main.c114
17 files changed, 443 insertions, 257 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e1547653d..bbeaa9ce4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -43,6 +43,7 @@ set(LIB_CORE_SRC
wee-secure.c wee-secure.h
wee-secure-buffer.c wee-secure-buffer.h
wee-secure-config.c wee-secure-config.h
+ wee-signal.c wee-signal.h
wee-string.c wee-string.h
wee-upgrade.c wee-upgrade.h
wee-upgrade-file.c wee-upgrade-file.h
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 62859c00f..29f7b2c61 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -67,6 +67,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-secure-buffer.h \
wee-secure-config.c \
wee-secure-config.h \
+ wee-signal.c \
+ wee-signal.h \
wee-string.c \
wee-string.h \
wee-upgrade.c \
diff --git a/src/core/hook/wee-hook-fd.c b/src/core/hook/wee-hook-fd.c
index 262dcacde..5b598283f 100644
--- a/src/core/hook/wee-hook-fd.c
+++ b/src/core/hook/wee-hook-fd.c
@@ -32,7 +32,6 @@
#include "../wee-hook.h"
#include "../wee-infolist.h"
#include "../wee-log.h"
-#include "../wee-util.h"
#include "../../gui/gui-chat.h"
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 49a904d24..353406825 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -5329,22 +5329,6 @@ command_reload_file (struct t_config_file *config_file)
}
/*
- * Reloads all configuration files.
- */
-
-void
-command_reload_files ()
-{
- struct t_config_file *ptr_config_file;
-
- for (ptr_config_file = config_files; ptr_config_file;
- ptr_config_file = ptr_config_file->next_config)
- {
- command_reload_file (ptr_config_file);
- }
-}
-
-/*
* Callback for command "/reload": reloads a configuration file.
*/
@@ -5378,7 +5362,11 @@ COMMAND_CALLBACK(reload)
}
else
{
- command_reload_files ();
+ for (ptr_config_file = config_files; ptr_config_file;
+ ptr_config_file = ptr_config_file->next_config)
+ {
+ command_reload_file (ptr_config_file);
+ }
}
return WEECHAT_RC_OK;
diff --git a/src/core/wee-command.h b/src/core/wee-command.h
index 4d2214d14..07193a911 100644
--- a/src/core/wee-command.h
+++ b/src/core/wee-command.h
@@ -89,6 +89,5 @@ extern void command_version_display (struct t_gui_buffer *buffer,
int send_to_buffer_as_input,
int translated_string,
int display_git_version);
-extern void command_reload_files ();
#endif /* WEECHAT_COMMAND_H */
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index d265fba8d..d352d08bc 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -303,6 +303,14 @@ struct t_config_option *config_plugin_extension;
struct t_config_option *config_plugin_path;
struct t_config_option *config_plugin_save_config_on_unload;
+/* config, signal section */
+
+struct t_config_option *config_signal_sighup;
+struct t_config_option *config_signal_sigquit;
+struct t_config_option *config_signal_sigterm;
+struct t_config_option *config_signal_sigusr1;
+struct t_config_option *config_signal_sigusr2;
+
/* other */
int config_length_nick_prefix_suffix = 0;
@@ -4566,6 +4574,63 @@ config_weechat_init_options ()
NULL, 0, 0, "on", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ /* signal */
+ ptr_section = config_file_new_section (weechat_config_file, "signal",
+ 0, 0,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if (!ptr_section)
+ {
+ config_file_free (weechat_config_file);
+ weechat_config_file = NULL;
+ return 0;
+ }
+
+ config_signal_sighup = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "sighup", "string",
+ N_("command to execute when the signal is received, "
+ "multiple commands can be separated by semicolons "
+ "(note: content is evaluated, see /help eval)"),
+ NULL, 0, 0,
+ "${if:${info:weechat_headless}?/reload:/quit -yes}", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ config_signal_sigquit = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "sigquit", "string",
+ N_("command to execute when the signal is received, "
+ "multiple commands can be separated by semicolons "
+ "(note: content is evaluated, see /help eval)"),
+ NULL, 0, 0, "/quit -yes", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ config_signal_sigterm = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "sigterm", "string",
+ N_("command to execute when the signal is received, "
+ "multiple commands can be separated by semicolons "
+ "(note: content is evaluated, see /help eval)"),
+ NULL, 0, 0, "/quit -yes", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ config_signal_sigusr1 = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "sigusr1", "string",
+ N_("command to execute when the signal is received, "
+ "multiple commands can be separated by semicolons "
+ "(note: content is evaluated, see /help eval)"),
+ NULL, 0, 0, "", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ config_signal_sigusr2 = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "sigusr2", "string",
+ N_("command to execute when the signal is received, "
+ "multiple commands can be separated by semicolons "
+ "(note: content is evaluated, see /help eval)"),
+ NULL, 0, 0, "", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
/* bars */
ptr_section = config_file_new_section (
weechat_config_file, "bar",
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index ba4068ee7..356641e6a 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -346,6 +346,12 @@ extern struct t_config_option *config_plugin_extension;
extern struct t_config_option *config_plugin_path;
extern struct t_config_option *config_plugin_save_config_on_unload;
+extern struct t_config_option *config_signal_sighup;
+extern struct t_config_option *config_signal_sigquit;
+extern struct t_config_option *config_signal_sigterm;
+extern struct t_config_option *config_signal_sigusr1;
+extern struct t_config_option *config_signal_sigusr2;
+
extern int config_length_nick_prefix_suffix;
extern int config_length_prefix_same_nick;
extern int config_length_prefix_same_nick_middle;
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index 73525201e..71ec34bdd 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -147,7 +147,7 @@ debug_dump_cb (const void *pointer, void *data,
*/
void
-debug_sigsegv ()
+debug_sigsegv_cb ()
{
debug_dump (1);
unhook_all ();
diff --git a/src/core/wee-debug.h b/src/core/wee-debug.h
index 617000973..f57bcf71f 100644
--- a/src/core/wee-debug.h
+++ b/src/core/wee-debug.h
@@ -24,7 +24,7 @@
struct t_gui_window_tree;
-extern void debug_sigsegv ();
+extern void debug_sigsegv_cb ();
extern void debug_windows_tree ();
extern void debug_memory ();
extern void debug_hdata ();
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 12f713ce1..ad565a12a 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -35,8 +35,8 @@
#include "wee-hashtable.h"
#include "wee-infolist.h"
#include "wee-log.h"
+#include "wee-signal.h"
#include "wee-string.h"
-#include "wee-util.h"
#include "../gui/gui-chat.h"
#include "../plugins/plugin.h"
@@ -514,7 +514,7 @@ hook_set (struct t_hook *hook, const char *property, const char *value)
if (!error || error[0])
{
/* not a number? look for signal by name */
- number = util_signal_search (value);
+ number = signal_search_name (value);
}
if (number >= 0)
{
diff --git a/src/core/wee-signal.c b/src/core/wee-signal.c
new file mode 100644
index 000000000..0765decf0
--- /dev/null
+++ b/src/core/wee-signal.c
@@ -0,0 +1,314 @@
+/*
+ * wee-signal.c - signal functions
+ *
+ * Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "weechat.h"
+#include "wee-signal.h"
+#include "wee-config.h"
+#include "wee-debug.h"
+#include "wee-eval.h"
+#include "wee-hook.h"
+#include "wee-input.h"
+#include "wee-log.h"
+#include "wee-string.h"
+#include "../gui/gui-buffer.h"
+#include "../plugins/plugin.h"
+
+
+struct t_signal signal_list[] =
+{ { SIGHUP, "hup" },
+ { SIGINT, "int" },
+ { SIGQUIT, "quit" },
+ { SIGKILL, "kill" },
+ { SIGTERM, "term" },
+ { SIGUSR1, "usr1" },
+ { SIGUSR2, "usr2" },
+ { 0, NULL },
+};
+
+volatile sig_atomic_t signal_sighup_count = 0;
+volatile sig_atomic_t signal_sigquit_count = 0;
+volatile sig_atomic_t signal_sigterm_count = 0;
+volatile sig_atomic_t signal_sigusr1_count = 0;
+volatile sig_atomic_t signal_sigusr2_count = 0;
+
+
+/*
+ * Callback for system signal SIGHUP.
+ */
+
+void
+signal_sighup_cb ()
+{
+ signal_sighup_count++;
+}
+
+/*
+ * Callback for system signal SIGQUIT.
+ */
+
+void
+signal_sigquit_cb ()
+{
+ signal_sigquit_count++;
+}
+
+/*
+ * Callback for system signal SIGTERM.
+ */
+
+void
+signal_sigterm_cb ()
+{
+ signal_sigterm_count++;
+}
+
+/*
+ * Callback for system signal SIGUSR1.
+ */
+
+void
+signal_sigusr1_cb ()
+{
+ signal_sigusr1_count++;
+}
+
+/*
+ * Callback for system signal SIGUSR2.
+ */
+
+void
+signal_sigusr2_cb ()
+{
+ signal_sigusr2_count++;
+}
+
+/*
+ * Gets a signal index with a signal number; only some commonly used signal
+ * names are supported here (see declaration of signal_list[]).
+ *
+ * Returns the index of signal in structure string_signal, -1 if not found.
+ */
+
+int
+signal_search_number (int signal_number)
+{
+ int i;
+
+ for (i = 0; signal_list[i].name; i++)
+ {
+ if (signal_list[i].signal == signal_number)
+ return i;
+ }
+
+ /* signal not found */
+ return -1;
+}
+
+/*
+ * Gets a signal number with a name; only some commonly used signal names are
+ * supported here (see declaration of signal_list[]).
+ *
+ * Returns the signal number, -1 if not found.
+ */
+
+int
+signal_search_name (const char *name)
+{
+ int i;
+
+ if (!name)
+ return -1;
+
+ for (i = 0; signal_list[i].name; i++)
+ {
+ if (string_strcasecmp (signal_list[i].name, name) == 0)
+ return signal_list[i].signal;
+ }
+
+ /* signal not found */
+ return -1;
+}
+
+/*
+ * Catches a system signal.
+ */
+
+void
+signal_catch (int signum, void (*handler)(int))
+{
+ struct sigaction act;
+
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = handler;
+ sigaction (signum, &act, NULL);
+}
+
+/*
+ * Sends a WeeChat signal on a system signal received.
+ *
+ * Returns:
+ * WEECHAT_RC_OK: the WeeChat handler must be executed
+ * WEECHAT_RC_OK_EAT: signal eaten, the WeeChat handler must NOT be executed
+ */
+
+int
+signal_send_to_weechat (int signal_index)
+{
+ int rc;
+ char str_signal[32];
+
+ if (signal_index < 0)
+ return WEECHAT_RC_OK;
+
+ snprintf (str_signal, sizeof (str_signal),
+ "signal_sig%s", signal_list[signal_index].name);
+
+ rc = hook_signal_send (str_signal, WEECHAT_HOOK_SIGNAL_STRING, NULL);
+
+ return (rc == WEECHAT_RC_OK_EAT) ? WEECHAT_RC_OK_EAT : WEECHAT_RC_OK;
+}
+
+/*
+ * Evaluates and executes the command bound to a signal.
+ */
+
+void
+signal_exec_command (int signal_index, const char *command)
+{
+ char *command_eval, **commands, **ptr_cmd, str_signal[32];
+ struct t_gui_buffer *weechat_buffer;
+
+ if (!command || !command[0])
+ return;
+
+ command_eval = eval_expression (command, NULL, NULL, NULL);
+ if (!command_eval)
+ return;
+
+ if (command_eval[0])
+ {
+ snprintf (str_signal, sizeof (str_signal),
+ "sig%s", signal_list[signal_index].name);
+ string_toupper (str_signal);
+ log_printf ("Signal %s received, executing command: %s",
+ str_signal, command_eval);
+ commands = string_split_command (command_eval, ';');
+ if (commands)
+ {
+ weechat_buffer = gui_buffer_search_main ();
+ for (ptr_cmd = commands; *ptr_cmd; ptr_cmd++)
+ {
+ (void) input_data (weechat_buffer, *ptr_cmd, NULL);
+ }
+ string_free_split_command (commands);
+ }
+ }
+ free (command_eval);
+}
+
+/*
+ * Handles a specific signal received:
+ */
+
+void
+signal_handle_number (int signal_number, int count, const char *command)
+{
+ int i, signal_index, rc;
+
+ if (count == 0)
+ return;
+
+ signal_index = signal_search_number (signal_number);
+ if (signal_index < 0)
+ return;
+
+ for (i = 0; i < count; i++)
+ {
+ rc = signal_send_to_weechat (signal_index);
+ if (rc == WEECHAT_RC_OK_EAT)
+ continue;
+ signal_exec_command (signal_index, command);
+ }
+}
+
+/*
+ * Handles signals received: sends WeeChat signal and executes the configured
+ * command (is signal not eaten).
+ */
+
+void
+signal_handle ()
+{
+ /* SIGUSR1 */
+ signal_handle_number (SIGUSR1, signal_sigusr1_count,
+ CONFIG_STRING(config_signal_sigusr1));
+ signal_sigusr1_count = 0;
+
+ /* SIGUSR2 */
+ signal_handle_number (SIGUSR2, signal_sigusr2_count,
+ CONFIG_STRING(config_signal_sigusr2));
+ signal_sigusr2_count = 0;
+
+ /* SIGHUP */
+ signal_handle_number (SIGHUP, signal_sighup_count,
+ CONFIG_STRING(config_signal_sighup));
+ signal_sighup_count = 0;
+
+ /* SIGQUIT */
+ signal_handle_number (SIGQUIT, signal_sigquit_count,
+ CONFIG_STRING(config_signal_sigquit));
+ signal_sigquit_count = 0;
+
+ /* SIGTERM */
+ signal_handle_number (SIGTERM, signal_sigterm_count,
+ CONFIG_STRING(config_signal_sigterm));
+ signal_sigterm_count = 0;
+}
+
+/*
+ * Initializes signal.
+ */
+
+void
+signal_init ()
+{
+ /* ignore some signals */
+ signal_catch (SIGINT, SIG_IGN);
+ signal_catch (SIGPIPE, SIG_IGN);
+
+ /* catch signals that can be customized */
+ signal_catch (SIGHUP, &signal_sighup_cb);
+ signal_catch (SIGQUIT, &signal_sigquit_cb);
+ signal_catch (SIGTERM, &signal_sigterm_cb);
+ signal_catch (SIGUSR1, &signal_sigusr1_cb);
+ signal_catch (SIGUSR2, &signal_sigusr2_cb);
+
+ /* in case of crash (oh no!) */
+ signal_catch (SIGSEGV, &debug_sigsegv_cb);
+}
diff --git a/src/core/wee-signal.h b/src/core/wee-signal.h
new file mode 100644
index 000000000..937986206
--- /dev/null
+++ b/src/core/wee-signal.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef WEECHAT_SIGNAL_H
+#define WEECHAT_SIGNAL_H
+
+struct t_signal
+{
+ int signal; /* signal number */
+ char *name; /* signal name, eg "hup" for SIGHUP */
+};
+
+extern struct t_signal signal_list[];
+
+extern int signal_search_number (int signal_number);
+extern int signal_search_name (const char *name);
+extern void signal_catch (int signum, void (*handler)(int));
+extern void signal_handle ();
+extern void signal_init ();
+
+#endif /* WEECHAT_SIGNAL_H */
diff --git a/src/core/wee-util.c b/src/core/wee-util.c
index f04a7cbfa..61a095645 100644
--- a/src/core/wee-util.c
+++ b/src/core/wee-util.c
@@ -115,16 +115,6 @@ struct t_rlimit_resource rlimit_resource[] =
};
#endif /* HAVE_SYS_RESOURCE_H */
-struct t_util_signal util_signals[] =
-{ { "hup", SIGHUP },
- { "int", SIGINT },
- { "quit", SIGQUIT },
- { "kill", SIGKILL },
- { "term", SIGTERM },
- { "usr1", SIGUSR1 },
- { "usr2", SIGUSR2 },
- { NULL, 0 },
-};
/*
* Sets resource limit.
@@ -440,68 +430,6 @@ util_parse_delay (const char *string_delay, long default_factor)
}
/*
- * Gets a signal number with a name; only some commonly used signal names are
- * supported here (see declaration of util_signals[]).
- *
- * Returns the signal number, -1 if not found.
- */
-
-int
-util_signal_search (const char *name)
-{
- int i;
-
- if (!name)
- return -1;
-
- for (i = 0; util_signals[i].name; i++)
- {
- if (string_strcasecmp (util_signals[i].name, name) == 0)
- return util_signals[i].signal;
- }
-
- /* signal not found */
- return -1;
-}
-
-/*
- * Gets a signal name with a signal number; only some commonly used signal
- * names are supported here (see declaration of util_signals[]).
- *
- * Returns the pointer to the signal name, NULL if not found.
- */
-
-const char *
-util_signal_search_number (int signal_number)
-{
- int i;
-
- for (i = 0; util_signals[i].name; i++)
- {
- if (util_signals[i].signal == signal_number)
- return util_signals[i].name;
- }
-
- /* signal not found */
- return NULL;
-}
-
-/*
- * Catches a system signal.
- */
-
-void
-util_catch_signal (int signum, void (*handler)(int))
-{
- struct sigaction act;
-
- sigemptyset (&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = handler;
- sigaction (signum, &act, NULL);
-}
-
-/*
* Returns the path to a temporary directory, the first valid directory in
* this list:
* - content of environment variable "TMPDIR"
diff --git a/src/core/wee-util.h b/src/core/wee-util.h
index d38d3084b..e7cf2a5cd 100644
--- a/src/core/wee-util.h
+++ b/src/core/wee-util.h
@@ -31,14 +31,6 @@ struct t_rlimit_resource
};
#endif /* HAVE_SYS_RESOURCE_H */
-struct t_util_signal
-{
- char *name; /* name of signal */
- int signal; /* signal number */
-};
-
-extern struct t_util_signal util_signals[];
-
/* limits */
extern void util_setrlimit ();
@@ -58,11 +50,6 @@ extern void util_get_time_diff (time_t time1, time_t time2,
extern long util_parse_delay (const char *string_delay, long default_factor);
-/* signal */
-extern int util_signal_search (const char *name);
-extern const char *util_signal_search_number (int signal_number);
-extern void util_catch_signal (int signum, void (*handler)(int));
-
/* files/directories */
extern char *util_get_temp_dir();
extern int util_mkdir_home (const char *directory, int mode);
diff --git a/src/core/weechat.c b/src/core/weechat.c
index 4f18c90be..6d97bfe35 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -68,6 +68,7 @@
#include "wee-proxy.h"
#include "wee-secure.h"
#include "wee-secure-config.h"
+#include "wee-signal.h"
#include "wee-string.h"
#include "wee-upgrade.h"
#include "wee-utf8.h"
@@ -99,7 +100,7 @@ time_t weechat_first_start_time = 0; /* start time (used by /uptime cmd) */
int weechat_upgrade_count = 0; /* number of /upgrade done */
struct timeval weechat_current_start_timeval; /* start time used to display */
/* duration of /upgrade */
-volatile sig_atomic_t weechat_quit = 0; /* = 1 if quit request from user */
+int weechat_quit = 0; /* = 1 if quit request from user */
volatile sig_atomic_t weechat_quit_signal = 0; /* signal received, */
/* WeeChat must quit */
volatile sig_atomic_t weechat_reload_signal = 0; /* signal received, */
@@ -689,36 +690,6 @@ weechat_locale_check ()
}
/*
- * Callback for system signal SIGHUP: reloads configuration.
- */
-
-void
-weechat_sighup ()
-{
- weechat_reload_signal = SIGHUP;
-}
-
-/*
- * Callback for system signal SIGQUIT: quits WeeChat.
- */
-
-void
-weechat_sigquit ()
-{
- weechat_quit_signal = SIGQUIT;
-}
-
-/*
- * Callback for system signal SIGTERM: quits WeeChat.
- */
-
-void
-weechat_sigterm ()
-{
- weechat_quit_signal = SIGTERM;
-}
-
-/*
* Shutdowns WeeChat.
*/
@@ -786,14 +757,7 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)())
weechat_first_start_time = time (NULL); /* initialize start time */
gettimeofday (&weechat_current_start_timeval, NULL);
- /* catch signals */
- util_catch_signal (SIGINT, SIG_IGN); /* signal ignored */
- util_catch_signal (SIGPIPE, SIG_IGN); /* signal ignored */
- util_catch_signal (SIGSEGV, &debug_sigsegv); /* crash dump */
- util_catch_signal (SIGHUP, &weechat_sighup); /* exit WeeChat */
- util_catch_signal (SIGQUIT, &weechat_sigquit); /* exit WeeChat */
- util_catch_signal (SIGTERM, &weechat_sigterm); /* exit WeeChat */
-
+ signal_init (); /* initialize signals */
hdata_init (); /* initialize hdata */
hook_init (); /* initialize hooks */
debug_init (); /* hook signals for debug */
diff --git a/src/core/weechat.h b/src/core/weechat.h
index c7eb4ba68..49614a804 100644
--- a/src/core/weechat.h
+++ b/src/core/weechat.h
@@ -109,7 +109,7 @@ extern int weechat_first_start;
extern time_t weechat_first_start_time;
extern struct timeval weechat_current_start_timeval;
extern int weechat_upgrade_count;
-extern volatile sig_atomic_t weechat_quit;
+extern int weechat_quit;
extern volatile sig_atomic_t weechat_quit_signal;
extern volatile sig_atomic_t weechat_reload_signal;
extern char *weechat_home;
diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c
index 15c95b8eb..4beec888b 100644
--- a/src/gui/curses/gui-curses-main.c
+++ b/src/gui/curses/gui-curses-main.c
@@ -35,9 +35,9 @@
#include "../../core/wee-config.h"
#include "../../core/wee-hook.h"
#include "../../core/wee-log.h"
+#include "../../core/wee-signal.h"
#include "../../core/wee-string.h"
#include "../../core/wee-utf8.h"
-#include "../../core/wee-util.h"
#include "../../core/wee-version.h"
#include "../../plugins/plugin.h"
#include "../gui-main.h"
@@ -164,10 +164,9 @@ gui_main_init ()
struct t_gui_bar_window *ptr_bar_win;
char title[256];
-#ifdef WEECHAT_HEADLESS
/* allow Ctrl-C to quit WeeChat in headless mode */
- util_catch_signal (SIGINT, &gui_main_signal_sigint);
-#endif /* WEECHAT_HEADLESS */
+ if (weechat_headless)
+ signal_catch (SIGINT, &gui_main_signal_sigint);
initscr ();
@@ -265,30 +264,6 @@ gui_main_init ()
}
/*
- * Returns signal name with a signal number.
- *
- * Note: result must be freed after use.
- */
-
-char *
-gui_main_get_signal_name (int signal_number)
-{
- const char *signal_name;
- char str_signal[32];
-
- signal_name = util_signal_search_number (signal_number);
- if (!signal_name)
- return NULL;
-
- snprintf (str_signal, sizeof (str_signal),
- "SIG%s",
- signal_name);
- string_toupper (str_signal);
-
- return strdup (str_signal);
-}
-
-/*
* Callback for system signal SIGWINCH: refreshes screen.
*/
@@ -299,82 +274,6 @@ gui_main_signal_sigwinch ()
}
/*
- * Sends a WeeChat signal on a system signal received.
- *
- * Returns:
- * WEECHAT_RC_OK: the WeeChat handler must be executed
- * WEECHAT_RC_OK_EAT: signal eaten, the WeeChat handler must NOT be executed
- */
-
-int
-gui_main_handle_signal (const char *signal_name)
-{
- int rc;
- char str_signal[32];
-
- if (!signal_name)
- return WEECHAT_RC_OK;
-
- snprintf (str_signal, sizeof (str_signal), "signal_%s", signal_name);
- string_tolower (str_signal);
-
- rc = hook_signal_send (str_signal, WEECHAT_HOOK_SIGNAL_STRING, NULL);
-
- return (rc == WEECHAT_RC_OK_EAT) ? WEECHAT_RC_OK_EAT : WEECHAT_RC_OK;
-}
-
-/*
- * Callback for signals received that will make WeeChat reload configuration.
- */
-
-void
-gui_main_handle_reload_signal ()
-{
- char *signal_name;
-
- signal_name = gui_main_get_signal_name (weechat_reload_signal);
-
- if (gui_main_handle_signal (signal_name) != WEECHAT_RC_OK_EAT)
- {
- log_printf (_("Signal %s received, reloading configuration..."),
- signal_name);
- command_reload_files ();
- }
-
- if (signal_name)
- free (signal_name);
-
- weechat_reload_signal = 0;
-}
-
-/*
- * Callback for signals received that will make WeeChat quit.
- */
-
-void
-gui_main_handle_quit_signals ()
-{
- char *signal_name;
-
- signal_name = gui_main_get_signal_name (weechat_quit_signal);
-
- if (gui_main_handle_signal (signal_name) != WEECHAT_RC_OK_EAT)
- {
- if (!weechat_quit)
- {
- log_printf (_("Signal %s received, exiting WeeChat..."),
- signal_name);
- (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
- weechat_quit = 1;
- }
- }
-
- if (signal_name)
- free (signal_name);
-
- weechat_quit_signal = 0;
-}
-/*
* Displays infos about ncurses lib.
*/
@@ -510,7 +409,7 @@ gui_main_loop ()
/* catch SIGWINCH signal: redraw screen */
if (!weechat_headless)
- util_catch_signal (SIGWINCH, &gui_main_signal_sigwinch);
+ signal_catch (SIGWINCH, &gui_main_signal_sigwinch);
/* hook stdin (read keyboard) */
if (weechat_headless)
@@ -566,10 +465,7 @@ gui_main_loop ()
hook_process_exec ();
/* handle signals received */
- if (weechat_reload_signal > 0)
- gui_main_handle_reload_signal ();
- if (weechat_quit_signal > 0)
- gui_main_handle_quit_signals ();
+ signal_handle ();
}
/* remove keyboard hook */