[mutter/wip/wayland-2: 42/42] Add a crash handler to restore the TTY and keyboard mode
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-2: 42/42] Add a crash handler to restore the TTY and keyboard mode
- Date: Tue, 16 Jul 2013 16:24:23 +0000 (UTC)
commit b066797f36b436dd30c2819595828782fa8f1e2a
Author: Giovanni Campagna <gcampagn redhat com>
Date: Tue Jul 16 16:39:32 2013 +0200
Add a crash handler to restore the TTY and keyboard mode
If mutter crashes on secondary VT, it leaves you with a raw keyboard
that doesn't switch with Alt+FN and no way to get out. At least,
let's provide a decent error message that we crash and let's
restore everything to sane defaults.
src/core/main.c | 34 ++++++++++++++++++++++++++++++++++
src/wayland/meta-tty.c | 15 ++++++++-------
src/wayland/meta-tty.h | 3 +++
3 files changed, 45 insertions(+), 7 deletions(-)
---
diff --git a/src/core/main.c b/src/core/main.c
index d545576..16c51da 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -365,6 +365,27 @@ on_sigterm (gpointer user_data)
return G_SOURCE_REMOVE;
}
+static void
+crash_handler (int signum)
+{
+ char buffer[256];
+ MetaWaylandCompositor *compositor;
+ MetaTTY *tty;
+
+ snprintf (buffer, 256, "Fatal server error: %s\n", strsignal (signum));
+ write (STDERR_FILENO, buffer, strlen (buffer));
+
+ compositor = meta_wayland_compositor_get_default ();
+ tty = meta_wayland_compositor_get_tty (compositor);
+
+ /* Passing FALSE ensures that we only do ioctls, which is
+ safe from a signal handler */
+ meta_tty_reset (tty, FALSE);
+
+ /* We can't continue with the default handling, so just exit here */
+ _exit(1);
+}
+
/**
* meta_init: (skip)
*
@@ -390,6 +411,19 @@ meta_init (void)
g_strerror (errno));
#endif
+ if (meta_is_display_server ())
+ {
+ act.sa_handler = crash_handler;
+
+ /* Ignore if we can't register signal handlers, worse
+ that can happen one needs the sysrq to get out of the VT */
+ sigaction (SIGABRT, &act, NULL);
+ sigaction (SIGSEGV, &act, NULL);
+ sigaction (SIGBUS, &act, NULL);
+ sigaction (SIGFPE, &act, NULL);
+ sigaction (SIGTRAP, &act, NULL);
+ }
+
/* Revert weston-launch brokenness */
sigemptyset (&empty_mask);
sigaddset (&empty_mask, SIGTERM);
diff --git a/src/wayland/meta-tty.c b/src/wayland/meta-tty.c
index b0161a4..c3a5a97 100644
--- a/src/wayland/meta-tty.c
+++ b/src/wayland/meta-tty.c
@@ -332,22 +332,23 @@ meta_tty_initable_init(GInitable *initable,
return FALSE;
}
-static void
-tty_reset (MetaTTY *tty)
+void
+meta_tty_reset (MetaTTY *tty,
+ gboolean warn_if_fail)
{
struct vt_mode mode = { 0 };
- if (ioctl (tty->fd, KDSKBMODE, tty->kb_mode))
+ if (ioctl (tty->fd, KDSKBMODE, tty->kb_mode) && warn_if_fail)
g_warning ("failed to restore keyboard mode: %s", strerror (errno));
- if (ioctl (tty->fd, KDSETMODE, KD_TEXT))
+ if (ioctl (tty->fd, KDSETMODE, KD_TEXT) && warn_if_fail)
g_warning ("failed to set KD_TEXT mode on tty: %s", strerror (errno));
- if (tcsetattr (tty->fd, TCSANOW, &tty->terminal_attributes) < 0)
+ if (tcsetattr (tty->fd, TCSANOW, &tty->terminal_attributes) < 0 && warn_if_fail)
g_warning ("could not restore terminal to canonical mode");
mode.mode = VT_AUTO;
- if (ioctl (tty->fd, VT_SETMODE, &mode) < 0)
+ if (ioctl (tty->fd, VT_SETMODE, &mode) < 0 && warn_if_fail)
g_warning ("could not reset vt handling\n");
if (tty->vt != tty->starting_vt)
@@ -372,7 +373,7 @@ meta_tty_finalize (GObject *object)
g_main_loop_unref (tty->nested_loop);
g_main_context_unref (tty->nested_context);
- tty_reset (tty);
+ meta_tty_reset (tty, TRUE);
close (tty->fd);
diff --git a/src/wayland/meta-tty.h b/src/wayland/meta-tty.h
index f5a2464..bf3dd51 100644
--- a/src/wayland/meta-tty.h
+++ b/src/wayland/meta-tty.h
@@ -42,6 +42,9 @@ gboolean meta_tty_activate_vt (MetaTTY *self,
int number,
GError **error);
+void meta_tty_reset (MetaTTY *self,
+ gboolean warn_if_fail);
+
G_END_DECLS
#endif /* META_TTY_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]