summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2016-05-10 13:41:59 +0200
committerBastien Nocera <hadess@hadess.net>2016-05-13 12:39:16 +0200
commitc0431d7990e628b00064fc5b47c66d3c69ba1138 (patch)
tree1dd86735d086e763f71854b89c0ddfc5079aa9c2
parent7f09161c41f9d0f737b3a92ffde2651f06216f82 (diff)
downloadbluez-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.ac2
-rw-r--r--src/bt-agent.c43
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);