summaryrefslogtreecommitdiff
path: root/monitor
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2012-02-27 10:35:31 -0800
committerMarcel Holtmann <marcel@holtmann.org>2012-02-27 10:35:31 -0800
commitcad9bb230a5e0ad5fac828eda65527ba6413e7ce (patch)
tree2395d354547a9748eba050d0e3ddc1c93e79a2a1 /monitor
parenta3877b43ee3bfadaf93c55e95ff4d9a5a4d0b891 (diff)
downloadbluez-cad9bb230a5e0ad5fac828eda65527ba6413e7ce.tar.gz
monitor: Use better signal integration
Diffstat (limited to 'monitor')
-rw-r--r--monitor/main.c17
-rw-r--r--monitor/mainloop.c80
-rw-r--r--monitor/mainloop.h5
3 files changed, 80 insertions, 22 deletions
diff --git a/monitor/main.c b/monitor/main.c
index 5b21e60ab..b4781e8bc 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 7a16f0edd..1cc787eb5 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 7a8869f93..04745d2d4 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);