mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
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
This commit is contained in:
parent
fc42b478bd
commit
fa3ca2bf10
@ -365,6 +365,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)
|
||||
*
|
||||
@ -390,6 +412,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"))
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user