diff options
author | Bastien Nocera <hadess@hadess.net> | 2016-05-10 13:41:59 +0200 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2016-05-13 12:39:16 +0200 |
commit | c0431d7990e628b00064fc5b47c66d3c69ba1138 (patch) | |
tree | 1dd86735d086e763f71854b89c0ddfc5079aa9c2 | |
parent | 7f09161c41f9d0f737b3a92ffde2651f06216f82 (diff) | |
download | bluez-tools-c0431d7990e628b00064fc5b47c66d3c69ba1138.tar.gz |
bt-agent: Fix incorrect Unix signal handling
The signal handler cannot do any sort of memory allocation, and it's
likely that it refuses to stop when wrapped in a systemd service
because of this.
Instead, use the g_unix_signal_add() helper which will call the handler
in a context that does allow us to re-read the PIN text file for
example.
Note that monitoring SIGUSR1 requires glib 2.36 or newer, as mentioned
in the documentation, even if g_unix_signal_add() is already available
in glib 2.30.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/bt-agent.c | 43 |
2 files changed, 25 insertions, 20 deletions
diff --git a/configure.ac b/configure.ac index 6211624..789140f 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ AC_HEADER_STDC # Check for the availability of dbus and glib libs PKG_PROG_PKG_CONFIG -PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.24.0]) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.36.0]) PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26.0 gio-unix-2.0 >= 2.26.0]) # Check for the availability of libreadline diff --git a/src/bt-agent.c b/src/bt-agent.c index feabaa6..07cfe86 100644 --- a/src/bt-agent.c +++ b/src/bt-agent.c @@ -35,6 +35,7 @@ #include <glib.h> #include <glib/gstdio.h> #include <gio/gio.h> +#include <glib-unix.h> #include "lib/dbus-common.h" #include "lib/helpers.h" @@ -126,21 +127,28 @@ static void _read_pin_file(const gchar *filename, GHashTable *pin_hash_table, gb return; } -static void signal_handler(int sig) +static gboolean +usr1_signal_handler(gpointer data) { - g_message("%s received", sig == SIGTERM ? "SIGTERM" : (sig == SIGUSR1 ? "SIGUSR1" : "SIGINT")); + g_message("SIGUSR1 received"); - if (sig == SIGUSR1 && pin_arg) - { - /* Re-read PIN's file */ - g_print("Re-reading PIN's file\n"); - _read_pin_file(pin_arg, pin_hash_table, FALSE); - } - else if (sig == SIGTERM || sig == SIGINT) - { - if (g_main_loop_is_running(mainloop)) - g_main_loop_quit(mainloop); - } + if (!pin_arg) + return G_SOURCE_CONTINUE; + + /* Re-read PIN's file */ + g_print("Re-reading PIN's file\n"); + _read_pin_file(pin_arg, pin_hash_table, FALSE); + + return G_SOURCE_CONTINUE; +} + +static gboolean +term_signal_handler(gpointer data) +{ + if (g_main_loop_is_running(mainloop)) + g_main_loop_quit(mainloop); + + return G_SOURCE_REMOVE; } static gchar *capability_arg = NULL; @@ -266,12 +274,9 @@ int main(int argc, char *argv[]) } /* Add SIGTERM/SIGINT/SIGUSR1 handlers */ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = signal_handler; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGUSR1, &sa, NULL); + g_unix_signal_add (SIGTERM, usr1_signal_handler, NULL); + g_unix_signal_add (SIGINT, term_signal_handler, NULL); + g_unix_signal_add (SIGUSR1, term_signal_handler, NULL); g_main_loop_run(mainloop); |