From ff91c696ff8f5f56da40e107cb5c321539758a81 Mon Sep 17 00:00:00 2001 From: Michal Srb Date: Tue, 16 Oct 2018 09:32:13 +0200 Subject: [PATCH xserver] xfree86: Only switch to original VT if it is active. If the X server is terminated while its VT is not active, it should not change the current VT. v2: Query current state in xf86CloseConsole using VT_GETSTATE instead of keeping track in xf86VTEnter/xf86VTLeave/etc. --- hw/xfree86/os-support/linux/lnx_init.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index 039dc4a4d..358d89f0f 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -272,101 +272,111 @@ xf86OpenConsole(void) xf86SetConsoleHandler(drain_console, NULL); } nTty = tty_attr; nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); nTty.c_oflag = 0; nTty.c_cflag = CREAD | CS8; nTty.c_lflag = 0; nTty.c_cc[VTIME] = 0; nTty.c_cc[VMIN] = 1; cfsetispeed(&nTty, 9600); cfsetospeed(&nTty, 9600); tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty); } } else { /* serverGeneration != 1 */ if (!xf86Info.ShareVTs && xf86Info.autoVTSwitch) { /* now get the VT */ if (!switch_to(xf86Info.vtno, "xf86OpenConsole")) FatalError("xf86OpenConsole: Switching VT failed\n"); } } } #pragma GCC diagnostic pop void xf86CloseConsole(void) { struct vt_mode VT; + struct vt_stat vts; int ret; if (xf86Info.ShareVTs) { close(xf86Info.consoleFd); return; } /* * unregister the drain_console handler * - what to do if someone else changed it in the meantime? */ xf86SetConsoleHandler(NULL, NULL); /* Back to text mode ... */ SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT)); if (ret < 0) xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n", strerror(errno)); SYSCALL(ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode)); tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr); SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT)); if (ret < 0) xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n", strerror(errno)); else { /* set dflt vt handling */ VT.mode = VT_AUTO; SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT)); if (ret < 0) xf86Msg(X_WARNING, "xf86CloseConsole: VT_SETMODE failed: %s\n", strerror(errno)); } if (xf86Info.autoVTSwitch) { /* - * Perform a switch back to the active VT when we were started - */ + * Perform a switch back to the active VT when we were started if our + * vt is active now. + */ if (activeVT >= 0) { - switch_to(activeVT, "xf86CloseConsole"); + SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts)); + if (ret < 0) { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_GETSTATE failed: %s\n", + strerror(errno)); + } else { + if (vts.v_active == xf86Info.vtno) { + switch_to(activeVT, "xf86CloseConsole"); + } + } activeVT = -1; } } close(xf86Info.consoleFd); /* make the vt-manager happy */ } #define CHECK_FOR_REQUIRED_ARGUMENT() \ if (((i + 1) >= argc) || (!argv[i + 1])) { \ ErrorF("Required argument to %s not specified\n", argv[i]); \ UseMsg(); \ FatalError("Required argument to %s not specified\n", argv[i]); \ } int xf86ProcessArgument(int argc, char *argv[], int i) { /* * Keep server from detaching from controlling tty. This is useful * when debugging (so the server can receive keyboard signals. */ if (!strcmp(argv[i], "-keeptty")) { KeepTty = TRUE; return 1; } if ((argv[i][0] == 'v') && (argv[i][1] == 't')) { if (sscanf(argv[i], "vt%2d", &xf86Info.vtno) == 0) { UseMsg(); xf86Info.vtno = -1; return 0; -- 2.18.4