Diff between a3877b43ee3bfadaf93c55e95ff4d9a5a4d0b891 and cad9bb230a5e0ad5fac828eda65527ba6413e7ce

Changed Files

File Additions Deletions Status
monitor/main.c +17 -0 modified
monitor/mainloop.c +58 -22 modified
monitor/mainloop.h +5 -0 modified

Full Patch

diff --git a/monitor/main.c b/monitor/main.c
index 5b21e60..b4781e8 100644
--- a/monitor/main.c
+++ b/monitor/main.c
@@ -34,12 +34,29 @@
 #include "control.h"
 #include "hcidump.h"
 
+static void signal_callback(int signum, void *user_data)
+{
+	switch (signum) {
+	case SIGINT:
+	case SIGTERM:
+		mainloop_quit();
+		break;
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	unsigned long filter_mask = 0;
+	sigset_t mask;
 
 	mainloop_init();
 
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+
+	mainloop_set_signal(&mask, signal_callback, NULL, NULL);
+
 	filter_mask |= PACKET_FILTER_SHOW_INDEX;
 	filter_mask |= PACKET_FILTER_SHOW_TIME;
 	filter_mask |= PACKET_FILTER_SHOW_ACL_DATA;
diff --git a/monitor/mainloop.c b/monitor/mainloop.c
index 7a16f0e..1cc787e 100644
--- a/monitor/mainloop.c
+++ b/monitor/mainloop.c
@@ -62,6 +62,16 @@ struct timeout_data {
 	void *user_data;
 };
 
+struct signal_data {
+	int fd;
+	sigset_t mask;
+	mainloop_signal_func callback;
+	mainloop_destroy_func destroy;
+	void *user_data;
+};
+
+static struct signal_data *signal_data;
+
 void mainloop_init(void)
 {
 	unsigned int i;
@@ -81,6 +91,7 @@ void mainloop_quit(void)
 
 static void signal_callback(int fd, uint32_t events, void *user_data)
 {
+	struct signal_data *data = user_data;
 	struct signalfd_siginfo si;
 	ssize_t result;
 
@@ -93,34 +104,28 @@ static void signal_callback(int fd, uint32_t events, void *user_data)
 	if (result != sizeof(si))
 		return;
 
-	switch (si.ssi_signo) {
-	case SIGINT:
-	case SIGTERM:
-		mainloop_quit();
-		break;
-	}
+	if (data->callback)
+		data->callback(si.ssi_signo, data->user_data);
 }
 
 int mainloop_run(void)
 {
 	unsigned int i;
-	sigset_t mask;
-	int fd;
 
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGINT);
-	sigaddset(&mask, SIGTERM);
+	if (signal_data) {
+		if (sigprocmask(SIG_BLOCK, &signal_data->mask, NULL) < 0)
+			return 1;
 
-	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
-		return 1;
+		signal_data->fd = signalfd(-1, &signal_data->mask,
+						SFD_NONBLOCK | SFD_CLOEXEC);
+		if (signal_data->fd < 0)
+			return 1;
 
-	fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
-	if (fd < 0)
-		return 1;
-
-	if (mainloop_add_fd(fd, EPOLLIN, signal_callback, NULL, NULL) < 0) {
-		close(fd);
-		return 1;
+		if (mainloop_add_fd(signal_data->fd, EPOLLIN,
+				signal_callback, signal_data, NULL) < 0) {
+			close(signal_data->fd);
+			return 1;
+		}
 	}
 
 	while (!epoll_terminate) {
@@ -139,8 +144,13 @@ int mainloop_run(void)
 		}
 	}
 
-	mainloop_remove_fd(fd);
-	close(fd);
+	if (signal_data) {
+		mainloop_remove_fd(signal_data->fd);
+		close(signal_data->fd);
+
+		if (signal_data->destroy)
+			signal_data->destroy(signal_data->user_data);
+	}
 
 	for (i = 0; i < MAX_MAINLOOP_ENTRIES; i++) {
 		struct mainloop_data *data = mainloop_list[i];
@@ -351,3 +361,29 @@ int mainloop_remove_timeout(int id)
 {
 	return mainloop_remove_fd(id);
 }
+
+int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback,
+				void *user_data, mainloop_destroy_func destroy)
+{
+	struct signal_data *data;
+
+	if (!mask || !callback)
+		return -EINVAL;
+
+	data = malloc(sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	memset(data, 0, sizeof(*data));
+	data->callback = callback;
+	data->destroy = destroy;
+	data->user_data = user_data;
+
+	data->fd = -1;
+	memcpy(&data->mask, mask, sizeof(sigset_t));
+
+	free(signal_data);
+	signal_data = data;
+
+	return 0;
+}
diff --git a/monitor/mainloop.h b/monitor/mainloop.h
index 7a8869f..04745d2 100644
--- a/monitor/mainloop.h
+++ b/monitor/mainloop.h
@@ -22,12 +22,14 @@
  *
  */
 
+#include <signal.h>
 #include <sys/epoll.h>
 
 typedef void (*mainloop_destroy_func) (void *user_data);
 
 typedef void (*mainloop_event_func) (int fd, uint32_t events, void *user_data);
 typedef void (*mainloop_timeout_func) (int id, void *user_data);
+typedef void (*mainloop_signal_func) (int signum, void *user_data);
 
 void mainloop_init(void);
 void mainloop_quit(void);
@@ -42,3 +44,6 @@ int mainloop_add_timeout(unsigned int seconds, mainloop_timeout_func callback,
 				void *user_data, mainloop_destroy_func destroy);
 int mainloop_modify_timeout(int fd, unsigned int seconds);
 int mainloop_remove_timeout(int id);
+
+int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback,
+				void *user_data, mainloop_destroy_func destroy);