From fc42b478bdbccc187e8b5a18c4da515020da7fed Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 16 Jul 2013 15:41:26 +0200 Subject: [PATCH] Fix handling SIGTERM while DRM-locked And at the same time, clean up the signal handling in the regular case. https://bugzilla.gnome.org/show_bug.cgi?id=705861 --- src/core/main.c | 70 +++--------------------------------------- src/wayland/meta-tty.c | 12 ++++++-- 2 files changed, 14 insertions(+), 68 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 0326d8ec3..f762f59c7 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -60,6 +60,7 @@ #endif #include +#include #include #include @@ -356,59 +357,12 @@ meta_finalize (void) #endif } -static int signal_pipe_fds[2] = { -1, -1 }; - -static void -signal_handler (int signum) -{ - if (signal_pipe_fds[1] >= 0) - { - switch (signum) - { - case SIGTERM: - write (signal_pipe_fds[1], "T", 1); - break; - default: - break; - } - } -} - static gboolean -on_signal (GIOChannel *source, - GIOCondition condition, - void *data) +on_sigterm (gpointer user_data) { - char signal; - int count; + meta_quit (EXIT_SUCCESS); - for (;;) - { - count = read (signal_pipe_fds[0], &signal, 1); - if (count == EINTR) - continue; - if (count < 0) - { - const char *msg = strerror (errno); - g_warning ("Error handling signal: %s", msg); - } - if (count != 1) - { - g_warning ("Unexpectedly failed to read byte from signal pipe\n"); - return TRUE; - } - break; - } - switch (signal) - { - case 'T': /* SIGTERM */ - meta_quit (META_EXIT_SUCCESS); - break; - default: - g_warning ("Spurious character '%c' read from signal pipe", signal); - } - - return TRUE; + return G_SOURCE_REMOVE; } /** @@ -422,7 +376,6 @@ meta_init (void) { struct sigaction act; sigset_t empty_mask; - GIOChannel *channel; sigemptyset (&empty_mask); act.sa_handler = SIG_IGN; @@ -437,20 +390,7 @@ meta_init (void) g_strerror (errno)); #endif - if (pipe (signal_pipe_fds) != 0) - g_printerr ("Failed to create signal pipe: %s\n", - g_strerror (errno)); - - channel = g_io_channel_unix_new (signal_pipe_fds[0]); - g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_signal, NULL); - g_io_channel_set_close_on_unref (channel, TRUE); - g_io_channel_unref (channel); - - act.sa_handler = &signal_handler; - if (sigaction (SIGTERM, &act, NULL) < 0) - g_printerr ("Failed to register SIGTERM handler: %s\n", - g_strerror (errno)); + g_unix_signal_add (SIGTERM, on_sigterm, NULL); if (g_getenv ("MUTTER_VERBOSE")) meta_set_verbose (TRUE); diff --git a/src/wayland/meta-tty.c b/src/wayland/meta-tty.c index 859f9cadc..fe867c0ff 100644 --- a/src/wayland/meta-tty.c +++ b/src/wayland/meta-tty.c @@ -64,6 +64,7 @@ struct _MetaTTY int input_source; GSource *vt_enter_source, *vt_leave_source; + GSource *nested_term; int vt, starting_vt; int kb_mode; }; @@ -83,7 +84,7 @@ G_DEFINE_TYPE_WITH_CODE (MetaTTY, meta_tty, G_TYPE_OBJECT, meta_tty_initable_iface_init)); static gboolean -vt_acquire_handler (gpointer user_data) +quit_nested_loop (gpointer user_data) { MetaTTY *tty = user_data; @@ -300,16 +301,20 @@ meta_tty_initable_init(GInitable *initable, goto err_kdmode; } - tty->vt_enter_source = g_unix_signal_source_new (SIGUSR2); - g_source_set_callback (tty->vt_enter_source, vt_acquire_handler, tty, NULL); tty->vt_leave_source = g_unix_signal_source_new (SIGUSR1); g_source_set_callback (tty->vt_leave_source, vt_release_handler, tty, NULL); + tty->vt_enter_source = g_unix_signal_source_new (SIGUSR2); + g_source_set_callback (tty->vt_enter_source, quit_nested_loop, tty, NULL); + tty->nested_term = g_unix_signal_source_new (SIGTERM); + g_source_set_callback (tty->nested_term, quit_nested_loop, tty, NULL); + tty->nested_context = g_main_context_new (); tty->nested_loop = g_main_loop_new (tty->nested_context, FALSE); g_source_attach (tty->vt_leave_source, NULL); g_source_attach (tty->vt_enter_source, tty->nested_context); + g_source_attach (tty->nested_term, tty->nested_context); return TRUE; @@ -364,6 +369,7 @@ meta_tty_finalize (GObject *object) g_source_destroy (tty->vt_enter_source); g_source_destroy (tty->vt_leave_source); + g_source_destroy (tty->nested_term); g_main_loop_unref (tty->nested_loop); g_main_context_unref (tty->nested_context);