From 919757ed0311eb1b5544e11d896fd1cffdc5a396 Mon Sep 17 00:00:00 2001 From: Ravi kumar Veeramally Date: Fri, 18 Oct 2013 16:10:02 +0300 Subject: [PATCH] android: Add missing signal handler functionality Added singal handling based on singalfd and removed sigaction based code. --- android/main.c | 82 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/android/main.c b/android/main.c index d44f88671..c3fb80ea2 100644 --- a/android/main.c +++ b/android/main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -54,23 +55,74 @@ static uint8_t mgmt_revision = 0; static uint16_t adapter_index = MGMT_INDEX_NONE; -static gboolean quit_eventloop(gpointer user_data) +static volatile sig_atomic_t __terminated = 0; + +static gboolean signal_handler(GIOChannel *channel, GIOCondition cond, + gpointer user_data) { - g_main_loop_quit(event_loop); + struct signalfd_siginfo si; + ssize_t result; + int fd; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) + return FALSE; + + fd = g_io_channel_unix_get_fd(channel); + + result = read(fd, &si, sizeof(si)); + if (result != sizeof(si)) + return FALSE; - return FALSE; + switch (si.ssi_signo) { + case SIGINT: + case SIGTERM: + if (__terminated == 0) { + info("Terminating"); + g_main_loop_quit(event_loop); + } + + __terminated = 1; + break; + } + + return TRUE; } -static void sig_term(int sig) +static guint setup_signalfd(void) { - static bool __terminated = false; + GIOChannel *channel; + guint source; + sigset_t mask; + int fd; + + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { + perror("Failed to set signal mask"); + return 0; + } - if (!__terminated) { - g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, - quit_eventloop, NULL); + fd = signalfd(-1, &mask, 0); + if (fd < 0) { + perror("Failed to create signal descriptor"); + return 0; } - __terminated = true; + channel = g_io_channel_unix_new(fd); + + g_io_channel_set_close_on_unref(channel, TRUE); + g_io_channel_set_encoding(channel, NULL, NULL); + g_io_channel_set_buffered(channel, FALSE); + + source = g_io_add_watch(channel, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + signal_handler, NULL); + + g_io_channel_unref(channel); + + return source; } static gboolean option_version = FALSE; @@ -242,7 +294,7 @@ int main(int argc, char *argv[]) { GOptionContext *context; GError *err = NULL; - struct sigaction sa; + guint signal; context = g_option_context_new(NULL); g_option_context_add_main_entries(context, options, NULL); @@ -265,14 +317,12 @@ int main(int argc, char *argv[]) } event_loop = g_main_loop_new(NULL, FALSE); + signal = setup_signalfd(); + if (!signal) + return EXIT_FAILURE; __btd_log_init("*", 0); - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sig_term; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - if (!init_mgmt_interface()) return EXIT_FAILURE; @@ -283,6 +333,8 @@ int main(int argc, char *argv[]) g_main_loop_run(event_loop); + g_source_remove(signal); + stop_sdp_server(); cleanup_mgmt_interface(); g_main_loop_unref(event_loop); -- 2.47.3