about summary refs log tree commit diff
path: root/src/main.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-05-04 21:35:57 +0200
committerMichael Biebl <biebl@debian.org>2011-05-04 21:35:57 +0200
commit3241555aff5c969104e492501097f4cb8837bcca (patch)
tree6d15a02d02a9f1bfcda6075ae2b8c71537d8038d /src/main.c
parente1b66c145e71e7bc6a06845dd17788fb7b8e158e (diff)
parent9f806e97a24bba61417ae312fcc0da40914266fb (diff)
Merge commit 'upstream/0.8.999' into experimental
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c133
1 files changed, 77 insertions, 56 deletions
diff --git a/src/main.c b/src/main.c
index 39e03de2..328c253d 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,69 +146,80 @@ 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
 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;
@@ -462,7 +474,7 @@ main (int argc, char *argv[])
 	char *log_level = NULL, *log_domains = NULL;
 	char **dns = NULL;
 	gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
-	gboolean success;
+	gboolean success, show_version = FALSE;
 	NMPolicy *policy = NULL;
 	NMVPNManager *vpn_manager = NULL;
 	NMDnsManager *dns_mgr = NULL;
@@ -475,6 +487,7 @@ main (int argc, char *argv[])
 	char *cfg_log_level = NULL, *cfg_log_domains = NULL;
 
 	GOptionEntry options[] = {
+		{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Print NetworkManager version and exit", NULL },
 		{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL },
 		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
 		{ "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &pidfile, "Specify the location of a PID file", "filename" },
@@ -483,16 +496,14 @@ main (int argc, char *argv[])
 		{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ','", "plugin1,plugin2" },
 		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" },
 		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &log_domains,
-		        "Log domains separated by ',': any combination of [NONE,HW,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,USER_SET,SYS_SET,SUSPEND,CORE,DEVICE,OLPC]",
+		        "Log domains separated by ',': any combination of\n"
+		        "                                          [NONE,HW,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,\n"
+		        "                                           WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,\n"
+		        "                                           AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,WIMAX]",
 		        "HW,RFKILL,WIFI" },
 		{NULL}
 	};
 
-	if (getuid () != 0) {
-		fprintf (stderr, "You must be root to run NetworkManager!\n");
-		exit (1);
-	}
-
 	if (!g_module_supported ()) {
 		fprintf (stderr, "GModules are not supported on your platform!\n");
 		exit (1);
@@ -520,6 +531,16 @@ main (int argc, char *argv[])
 		exit (1);
 	}
 
+	if (show_version) {
+		fprintf (stdout, NM_DIST_VERSION "\n");
+		exit (0);
+	}
+
+	if (getuid () != 0) {
+		fprintf (stderr, "You must be root to run NetworkManager!\n");
+		exit (1);
+	}
+
 	/* Make GIO ignore the remote VFS service; otherwise it tries to use the
 	 * session bus to contact the remote service, and NM shouldn't ever be
 	 * talking on the session bus.  See rh #588745