mirror of git://git.sysmocom.de/ofono
Use signalfd for signal handling
This commit is contained in:
parent
18e8c906c5
commit
adfb6c9d60
84
src/main.c
84
src/main.c
|
@ -30,13 +30,13 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
|
||||||
#include "ofono.h"
|
#include "ofono.h"
|
||||||
|
|
||||||
#define SHUTDOWN_GRACE_SECONDS 10
|
#define SHUTDOWN_GRACE_SECONDS 10
|
||||||
|
|
||||||
static GMainLoop *event_loop;
|
static GMainLoop *event_loop;
|
||||||
static volatile sig_atomic_t terminated = 0;
|
|
||||||
|
|
||||||
void __ofono_exit()
|
void __ofono_exit()
|
||||||
{
|
{
|
||||||
|
@ -49,26 +49,36 @@ static gboolean quit_eventloop(gpointer user_data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_debug(int sig)
|
static gboolean signal_cb(GIOChannel *channel, GIOCondition cond, gpointer data)
|
||||||
{
|
{
|
||||||
__ofono_toggle_debug();
|
int signal_fd = GPOINTER_TO_INT(data);
|
||||||
}
|
struct signalfd_siginfo si;
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
static gboolean initiate_shutdown(gpointer user_data)
|
if (cond & (G_IO_NVAL | G_IO_ERR))
|
||||||
{
|
return FALSE;
|
||||||
g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, quit_eventloop, NULL);
|
|
||||||
__ofono_modem_shutdown();
|
|
||||||
|
|
||||||
return FALSE;
|
res = read(signal_fd, &si, sizeof(si));
|
||||||
}
|
if (res != sizeof(si))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
static void sig_term(int sig)
|
switch (si.ssi_signo) {
|
||||||
{
|
case SIGINT:
|
||||||
if (terminated > 0)
|
case SIGTERM:
|
||||||
return;
|
g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
|
||||||
|
quit_eventloop, NULL);
|
||||||
|
__ofono_modem_shutdown();
|
||||||
|
break;
|
||||||
|
case SIGUSR2:
|
||||||
|
__ofono_toggle_debug();
|
||||||
|
break;
|
||||||
|
case SIGPIPE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
terminated = 1;
|
return TRUE;
|
||||||
g_idle_add(initiate_shutdown, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void system_bus_disconnected(DBusConnection *conn, void *user_data)
|
static void system_bus_disconnected(DBusConnection *conn, void *user_data)
|
||||||
|
@ -94,9 +104,36 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
struct sigaction sa;
|
sigset_t mask;
|
||||||
DBusConnection *conn;
|
DBusConnection *conn;
|
||||||
DBusError error;
|
DBusError error;
|
||||||
|
int signal_fd;
|
||||||
|
GIOChannel *signal_io;
|
||||||
|
int signal_source;
|
||||||
|
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGTERM);
|
||||||
|
sigaddset(&mask, SIGINT);
|
||||||
|
sigaddset(&mask, SIGUSR2);
|
||||||
|
sigaddset(&mask, SIGPIPE);
|
||||||
|
|
||||||
|
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
|
||||||
|
perror("Can't set signal mask");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_fd = signalfd(-1, &mask, 0);
|
||||||
|
if (signal_fd < 0) {
|
||||||
|
perror("Can't create signal filedescriptor");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_io = g_io_channel_unix_new(signal_fd);
|
||||||
|
g_io_channel_set_close_on_unref(signal_io, TRUE);
|
||||||
|
signal_source = g_io_add_watch(signal_io,
|
||||||
|
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
|
||||||
|
signal_cb, GINT_TO_POINTER(signal_fd));
|
||||||
|
g_io_channel_unref(signal_io);
|
||||||
|
|
||||||
#ifdef NEED_THREADS
|
#ifdef NEED_THREADS
|
||||||
if (g_thread_supported() == FALSE)
|
if (g_thread_supported() == FALSE)
|
||||||
|
@ -159,18 +196,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
__ofono_plugin_init(NULL, NULL);
|
__ofono_plugin_init(NULL, NULL);
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_flags = SA_NOCLDSTOP;
|
|
||||||
sa.sa_handler = sig_term;
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
|
|
||||||
sa.sa_handler = sig_debug;
|
|
||||||
sigaction(SIGUSR2, &sa, NULL);
|
|
||||||
|
|
||||||
sa.sa_handler = SIG_IGN;
|
|
||||||
sigaction(SIGPIPE, &sa, NULL);
|
|
||||||
|
|
||||||
g_main_loop_run(event_loop);
|
g_main_loop_run(event_loop);
|
||||||
|
|
||||||
__ofono_plugin_cleanup();
|
__ofono_plugin_cleanup();
|
||||||
|
@ -181,6 +206,7 @@ int main(int argc, char **argv)
|
||||||
dbus_connection_unref(conn);
|
dbus_connection_unref(conn);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
g_source_remove(signal_source);
|
||||||
g_main_loop_unref(event_loop);
|
g_main_loop_unref(event_loop);
|
||||||
|
|
||||||
__ofono_log_cleanup();
|
__ofono_log_cleanup();
|
||||||
|
|
Loading…
Reference in New Issue