diff options
| author | Michael Biebl <biebl@debian.org> | 2011-04-21 10:43:09 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2011-04-21 10:43:09 +0200 |
| commit | 8aefc77115a9b89e96ff224e659e2271912a8295 (patch) | |
| tree | 2aeaf38cdc77553c0bf417fb632c2a3d5e7adbc7 /src/main.c | |
| parent | 2fbd59597fe985d6feb382bf35145dcf2f481060 (diff) | |
| parent | 8baa1aca8dfd35e3190d7d5655eb83b5b901e263 (diff) | |
Merge commit 'upstream/0.8.4.0'
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/src/main.c b/src/main.c index b22c769d..da63930b 100644 --- a/src/main.c +++ b/src/main.c @@ -65,6 +65,7 @@ */ static NMManager *manager = NULL; static GMainLoop *main_loop = NULL; +static int quit_pipe[2] = { -1, -1 }; typedef struct { time_t time; @@ -145,62 +146,62 @@ static gboolean quit_early = FALSE; static void nm_signal_handler (int signo) { - static int in_fatal = 0; + static int in_fatal = 0, x; /* avoid loops */ if (in_fatal > 0) return; ++in_fatal; - switch (signo) - { - case SIGSEGV: - case SIGBUS: - case SIGILL: - case SIGABRT: - nm_log_warn (LOGD_CORE, "caught signal %d. Generating backtrace...", signo); - nm_logging_backtrace (); - exit (1); - break; - - case SIGFPE: - case SIGPIPE: - /* let the fatal signals interrupt us */ - --in_fatal; - - nm_log_warn (LOGD_CORE, "caught signal %d, shutting down abnormally. Generating backtrace...", signo); - nm_logging_backtrace (); - g_main_loop_quit (main_loop); - break; - - case SIGINT: - case SIGTERM: - /* let the fatal signals interrupt us */ - --in_fatal; - - nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo); - quit_early = TRUE; - g_main_loop_quit (main_loop); - break; - - case SIGHUP: - --in_fatal; - /* FIXME: - * Reread config stuff like system config files, VPN service files, etc - */ - break; - - case SIGUSR1: - --in_fatal; - /* FIXME: - * Play with log levels or something - */ - break; - - default: - signal (signo, nm_signal_handler); - break; + switch (signo) { + case SIGSEGV: + case SIGBUS: + case SIGILL: + case SIGABRT: + nm_log_warn (LOGD_CORE, "caught signal %d. Generating backtrace...", signo); + nm_logging_backtrace (); + exit (1); + break; + case SIGFPE: + case SIGPIPE: + /* let the fatal signals interrupt us */ + --in_fatal; + nm_log_warn (LOGD_CORE, "caught signal %d, shutting down abnormally. Generating backtrace...", signo); + nm_logging_backtrace (); + x = write (quit_pipe[1], "X", 1); + break; + case SIGINT: + case SIGTERM: + /* let the fatal signals interrupt us */ + --in_fatal; + nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo); + quit_early = TRUE; + x = write (quit_pipe[1], "X", 1); + break; + case SIGHUP: + --in_fatal; + /* Reread config stuff like system config files, VPN service files, etc */ + break; + case SIGUSR1: + --in_fatal; + /* Play with log levels or something */ + break; + default: + signal (signo, nm_signal_handler); + break; + } +} + +static gboolean +quit_watch (GIOChannel *src, GIOCondition condition, gpointer user_data) +{ + + if (condition & G_IO_IN) { + nm_log_warn (LOGD_CORE, "quit request received, terminating..."); + g_main_loop_quit (main_loop); } + + return FALSE; } static void @@ -208,6 +209,17 @@ setup_signals (void) { struct sigaction action; sigset_t mask; + GIOChannel *quit_channel; + + /* Set up our quit pipe */ + if (pipe (quit_pipe) < 0) { + fprintf (stderr, "Failed to initialze SIGTERM pipe: %d", errno); + exit (1); + } + fcntl (quit_pipe[1], F_SETFL, O_NONBLOCK | fcntl (quit_pipe[1], F_GETFL)); + + quit_channel = g_io_channel_unix_new (quit_pipe[0]); + g_io_add_watch_full (quit_channel, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR, quit_watch, NULL, NULL); sigemptyset (&mask); action.sa_handler = nm_signal_handler; |