mirror of
https://github.com/brl/mutter.git
synced 2025-08-04 23:54:40 +00: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:
@@ -365,6 +365,28 @@ on_sigterm (gpointer user_data)
|
|||||||
return G_SOURCE_REMOVE;
|
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)
|
* meta_init: (skip)
|
||||||
*
|
*
|
||||||
@@ -390,6 +412,19 @@ meta_init (void)
|
|||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
#endif
|
#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);
|
g_unix_signal_add (SIGTERM, on_sigterm, NULL);
|
||||||
|
|
||||||
if (g_getenv ("MUTTER_VERBOSE"))
|
if (g_getenv ("MUTTER_VERBOSE"))
|
||||||
|
@@ -334,22 +334,23 @@ meta_tty_initable_init(GInitable *initable,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
tty_reset (MetaTTY *tty)
|
meta_tty_reset (MetaTTY *tty,
|
||||||
|
gboolean warn_if_fail)
|
||||||
{
|
{
|
||||||
struct vt_mode mode = { 0 };
|
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));
|
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));
|
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");
|
g_warning ("could not restore terminal to canonical mode");
|
||||||
|
|
||||||
mode.mode = VT_AUTO;
|
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");
|
g_warning ("could not reset vt handling\n");
|
||||||
|
|
||||||
if (tty->vt != tty->starting_vt)
|
if (tty->vt != tty->starting_vt)
|
||||||
@@ -374,7 +375,7 @@ meta_tty_finalize (GObject *object)
|
|||||||
g_main_loop_unref (tty->nested_loop);
|
g_main_loop_unref (tty->nested_loop);
|
||||||
g_main_context_unref (tty->nested_context);
|
g_main_context_unref (tty->nested_context);
|
||||||
|
|
||||||
tty_reset (tty);
|
meta_tty_reset (tty, TRUE);
|
||||||
|
|
||||||
close (tty->fd);
|
close (tty->fd);
|
||||||
|
|
||||||
|
@@ -42,6 +42,9 @@ gboolean meta_tty_activate_vt (MetaTTY *self,
|
|||||||
int number,
|
int number,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
void meta_tty_reset (MetaTTY *self,
|
||||||
|
gboolean warn_if_fail);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* META_TTY_H */
|
#endif /* META_TTY_H */
|
||||||
|
Reference in New Issue
Block a user