summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2009-11-05 14:47:47 -0500
committerRay Strode <rstrode@redhat.com>2009-11-20 11:16:02 -0500
commitec7a3c516d36921d49fc757d6afae5e88731f47f (patch)
treef927deff804ab645a05d20e3064c68e824f9d212 /src
parent1acefb9eacfa617c3eacd9fadd823d869d016b22 (diff)
downloadmetacity-ec7a3c516d36921d49fc757d6afae5e88731f47f.tar.gz
metacity-ec7a3c516d36921d49fc757d6afae5e88731f47f.tar.bz2
Don't call meta_finalize from SIGTERM handler
It's not a legal function to call from a signal handler. Instead defer until going back to the main loop. https://bugzilla.gnome.org/show_bug.cgi?id=600864
Diffstat (limited to 'src')
-rw-r--r--src/core/main.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/core/main.c b/src/core/main.c
index a36a396..509c650 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -67,6 +67,7 @@
#include <fcntl.h>
#include <locale.h>
#include <time.h>
+#include <unistd.h>
/**
* The exit code we'll return to our parent process when we eventually die.
@@ -369,12 +370,24 @@ meta_finalize (void)
CurrentTime); /* I doubt correct timestamps matter here */
}
+static int sigterm_pipe_fds[2] = { -1, -1 };
+
static void
sigterm_handler (int signum)
{
- meta_finalize ();
+ if (sigterm_pipe_fds[1] >= 0)
+ {
+ write (sigterm_pipe_fds[1], "", 1);
+ close (sigterm_pipe_fds[1]);
+ sigterm_pipe_fds[1] = -1;
+ }
+}
- exit (meta_exit_code);
+static gboolean
+on_sigterm (void)
+{
+ meta_quit (META_EXIT_SUCCESS);
+ return FALSE;
}
static guint sigchld_signal_id = 0;
@@ -422,6 +435,7 @@ main (int argc, char **argv)
"Pango", "GLib-GObject", "GThread"
};
guint i;
+ GIOChannel *channel;
if (!g_thread_supported ())
g_thread_init (NULL);
@@ -444,6 +458,16 @@ main (int argc, char **argv)
g_strerror (errno));
#endif
+ if (pipe (sigterm_pipe_fds) != 0)
+ g_printerr ("Failed to create SIGTERM pipe: %s\n",
+ g_strerror (errno));
+
+ channel = g_io_channel_unix_new (sigterm_pipe_fds[0]);
+ g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL);
+ g_io_channel_set_close_on_unref (channel, TRUE);
+ g_io_channel_unref (channel);
+
act.sa_handler = &sigterm_handler;
if (sigaction (SIGTERM, &act, NULL) < 0)
g_printerr ("Failed to register SIGTERM handler: %s\n",