[mutter/wip/wayland-work: 47/63] 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-work: 47/63] Add a crash handler to restore the TTY and keyboard mode
- Date: Wed, 21 Aug 2013 16:23:50 +0000 (UTC)
commit 6440dcba593bb220b8822d2f58cfdb1acc4745eb
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.
https://bugzilla.gnome.org/show_bug.cgi?id=705861
src/core/main.c | 35 +++++++++++++++++++++++++++++++++++
src/wayland/meta-tty.c | 15 ++++++++-------
src/wayland/meta-tty.h | 3 +++
3 files changed, 46 insertions(+), 7 deletions(-)
---
diff --git a/src/core/main.c b/src/core/main.c
index 5f1f4da..9b70d2a 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -361,6 +361,28 @@ 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: %d\n", 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 */
+ if (tty)
+ meta_tty_reset (tty, FALSE);
+
+ /* We can't continue with the default handling, so just exit here */
+ _exit(1);
+}
+
/**
* meta_init: (skip)
*
@@ -386,6 +408,19 @@ meta_init (void)
g_strerror (errno));
#endif
+ if (meta_is_wayland_compositor ())
+ {
+ 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);
+ }
+
g_unix_signal_add (SIGTERM, on_sigterm, NULL);
if (g_getenv ("MUTTER_VERBOSE"))
diff --git a/src/wayland/meta-tty.c b/src/wayland/meta-tty.c
index fe867c0..bb735af 100644
--- a/src/wayland/meta-tty.c
+++ b/src/wayland/meta-tty.c
@@ -334,22 +334,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)
@@ -374,7 +375,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]