9d0fee0
From 92bc12b7085ff80d4f5a2389b5a00cda501e27c7 Mon Sep 17 00:00:00 2001
943ff73
From: Hans de Goede <hdegoede@redhat.com>
943ff73
Date: Wed, 21 Jan 2015 09:31:39 +0100
9d0fee0
Subject: [PATCH v2 1/3] linux: Add linux_parse_vt_settings and
9d0fee0
 linux_get_keeptty helpers
943ff73
943ff73
systemd-logind integration does not work when starting X on a new tty, as
943ff73
that detaches X from the current session and after hat systemd-logind revokes
943ff73
all rights on any already open fds and refuses to open new fds for X.
943ff73
943ff73
This means that currently e.g. "startx -- vt7" breaks, and breaks badly,
943ff73
requiring ssh access to the system to kill X.
943ff73
943ff73
The fix for this is easy, we must not use systemd-logind integration when
943ff73
not using KeepTty, or iow we may only use systemd-logind integration together
943ff73
with KeepTty.
943ff73
943ff73
But the final KeepTty value is not known until the code to chose which vtno to
943ff73
run on has been called, which currently happens after intializing
943ff73
systemd-logind.
943ff73
943ff73
This commit is step 1 in fixing the "startx -- vt7" breakage, it factors out
943ff73
the linux xf86OpenConsole bits which set xf86Info.vtno and keepTty so that
943ff73
these can be called earlier. Calling this earlier is safe as this code has
943ff73
no side effects other than setting xf86Info.vtno and keepTty.
943ff73
943ff73
Note this basically only moves a large chunk of xf86OpenConsole() into
9d0fee0
linux_parse_vt_settings() without changing a single line of it, this is
9d0fee0
hard to see in the diff because the identation level has changed.
943ff73
943ff73
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
9d0fee0
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
943ff73
---
943ff73
Changes in v2:
943ff73
-Rename linux_get_vtno to linux_parse_vt_settings
9d0fee0
Changes in v3:
9d0fee0
-Carry the rename of linux_get_vtno to linux_parse_vt_settings over into
9d0fee0
 the commit msg
943ff73
---
943ff73
 hw/xfree86/os-support/linux/linux.h    |  32 +++++++++
943ff73
 hw/xfree86/os-support/linux/lnx_init.c | 122 ++++++++++++++++++++-------------
943ff73
 2 files changed, 105 insertions(+), 49 deletions(-)
943ff73
 create mode 100644 hw/xfree86/os-support/linux/linux.h
943ff73
943ff73
diff --git a/hw/xfree86/os-support/linux/linux.h b/hw/xfree86/os-support/linux/linux.h
943ff73
new file mode 100644
943ff73
index 0000000..8cb8e3d
943ff73
--- /dev/null
943ff73
+++ b/hw/xfree86/os-support/linux/linux.h
943ff73
@@ -0,0 +1,32 @@
943ff73
+/*
943ff73
+ * Copyright © 2015 Red Hat, Inc.
943ff73
+ *
943ff73
+ * Permission is hereby granted, free of charge, to any person obtaining a
943ff73
+ * copy of this software and associated documentation files (the "Software"),
943ff73
+ * to deal in the Software without restriction, including without limitation
943ff73
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
943ff73
+ * and/or sell copies of the Software, and to permit persons to whom the
943ff73
+ * Software is furnished to do so, subject to the following conditions:
943ff73
+ *
943ff73
+ * The above copyright notice and this permission notice (including the next
943ff73
+ * paragraph) shall be included in all copies or substantial portions of the
943ff73
+ * Software.
943ff73
+ *
943ff73
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
943ff73
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
943ff73
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
943ff73
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
943ff73
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
943ff73
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
943ff73
+ * DEALINGS IN THE SOFTWARE.
943ff73
+ *
943ff73
+ * Author: Hans de Goede <hdegoede@redhat.com>
943ff73
+ */
943ff73
+
943ff73
+#ifndef XF86_LINUX_H
943ff73
+#define XF86_LINUX_H
943ff73
+
943ff73
+void linux_parse_vt_settings(void);
943ff73
+int linux_get_keeptty(void);
943ff73
+
943ff73
+#endif
943ff73
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
943ff73
index 9485307..22c61bf 100644
943ff73
--- a/hw/xfree86/os-support/linux/lnx_init.c
943ff73
+++ b/hw/xfree86/os-support/linux/lnx_init.c
943ff73
@@ -31,6 +31,7 @@
943ff73
 #include <X11/Xmd.h>
943ff73
 
943ff73
 #include "compiler.h"
943ff73
+#include "linux.h"
943ff73
 
943ff73
 #include "xf86.h"
943ff73
 #include "xf86Priv.h"
943ff73
@@ -80,71 +81,94 @@ switch_to(int vt, const char *from)
943ff73
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
943ff73
 
943ff73
 void
943ff73
-xf86OpenConsole(void)
943ff73
+linux_parse_vt_settings(void)
943ff73
 {
943ff73
     int i, fd = -1, ret, current_vt = -1;
943ff73
-    struct vt_mode VT;
943ff73
     struct vt_stat vts;
943ff73
     struct stat st;
943ff73
     MessageType from = X_PROBED;
943ff73
     const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
943ff73
-    const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
943ff73
 
943ff73
-    if (serverGeneration == 1) {
943ff73
-        /*
943ff73
-         * setup the virtual terminal manager
943ff73
-         */
943ff73
-        if (xf86Info.vtno != -1) {
943ff73
-            from = X_CMDLINE;
943ff73
-        }
943ff73
-        else {
943ff73
+    /* Only do this once */
943ff73
+    static int vt_settings_parsed = 0;
943ff73
 
943ff73
-            i = 0;
943ff73
-            while (tty0[i] != NULL) {
943ff73
-                if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0)
943ff73
-                    break;
943ff73
-                i++;
943ff73
-            }
943ff73
+    if (vt_settings_parsed)
943ff73
+        return;
943ff73
 
943ff73
-            if (fd < 0)
943ff73
-                FatalError("xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
943ff73
-                           strerror(errno));
943ff73
+    /*
943ff73
+     * setup the virtual terminal manager
943ff73
+     */
943ff73
+    if (xf86Info.vtno != -1) {
943ff73
+        from = X_CMDLINE;
943ff73
+    }
943ff73
+    else {
943ff73
 
943ff73
-            if (xf86Info.ShareVTs) {
943ff73
-                SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
943ff73
-                if (ret < 0)
943ff73
-                    FatalError("xf86OpenConsole: Cannot find the current"
943ff73
-                               " VT (%s)\n", strerror(errno));
943ff73
-                xf86Info.vtno = vts.v_active;
943ff73
-            }
943ff73
-            else {
943ff73
-                SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
943ff73
-                if (ret < 0)
943ff73
-                    FatalError("xf86OpenConsole: Cannot find a free VT: "
943ff73
-                               "%s\n", strerror(errno));
943ff73
-                if (xf86Info.vtno == -1)
943ff73
-                    FatalError("xf86OpenConsole: Cannot find a free VT\n");
943ff73
-            }
943ff73
-            close(fd);
943ff73
+        i = 0;
943ff73
+        while (tty0[i] != NULL) {
943ff73
+            if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0)
943ff73
+                break;
943ff73
+            i++;
943ff73
         }
943ff73
 
943ff73
-        xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
943ff73
+        if (fd < 0)
943ff73
+            FatalError("parse_vt_settings: Cannot open /dev/tty0 (%s)\n",
943ff73
+                       strerror(errno));
943ff73
 
943ff73
-        /* Some of stdin / stdout / stderr maybe redirected to a file */
943ff73
-        for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) {
943ff73
-            ret = fstat(i, &st);
943ff73
-            if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) {
943ff73
-                current_vt = minor(st.st_rdev);
943ff73
-                break;
943ff73
-            }
943ff73
+        if (xf86Info.ShareVTs) {
943ff73
+            SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
943ff73
+            if (ret < 0)
943ff73
+                FatalError("parse_vt_settings: Cannot find the current"
943ff73
+                           " VT (%s)\n", strerror(errno));
943ff73
+            xf86Info.vtno = vts.v_active;
943ff73
         }
943ff73
+        else {
943ff73
+            SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
943ff73
+            if (ret < 0)
943ff73
+                FatalError("parse_vt_settings: Cannot find a free VT: "
943ff73
+                           "%s\n", strerror(errno));
943ff73
+            if (xf86Info.vtno == -1)
943ff73
+                FatalError("parse_vt_settings: Cannot find a free VT\n");
943ff73
+        }
943ff73
+        close(fd);
943ff73
+    }
943ff73
+
943ff73
+    xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
943ff73
 
943ff73
-        if (!KeepTty && current_vt == xf86Info.vtno) {
943ff73
-            xf86Msg(X_PROBED,
943ff73
-                    "controlling tty is VT number %d, auto-enabling KeepTty\n",
943ff73
-                    current_vt);
943ff73
-            KeepTty = TRUE;
943ff73
+    /* Some of stdin / stdout / stderr maybe redirected to a file */
943ff73
+    for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) {
943ff73
+        ret = fstat(i, &st);
943ff73
+        if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) {
943ff73
+            current_vt = minor(st.st_rdev);
943ff73
+            break;
943ff73
         }
943ff73
+    }
943ff73
+
943ff73
+    if (!KeepTty && current_vt == xf86Info.vtno) {
943ff73
+        xf86Msg(X_PROBED,
943ff73
+                "controlling tty is VT number %d, auto-enabling KeepTty\n",
943ff73
+                current_vt);
943ff73
+        KeepTty = TRUE;
943ff73
+    }
943ff73
+
943ff73
+    vt_settings_parsed = 1;
943ff73
+}
943ff73
+
943ff73
+int
943ff73
+linux_get_keeptty(void)
943ff73
+{
943ff73
+    return KeepTty;
943ff73
+}
943ff73
+
943ff73
+void
943ff73
+xf86OpenConsole(void)
943ff73
+{
943ff73
+    int i, ret;
943ff73
+    struct vt_stat vts;
943ff73
+    struct vt_mode VT;
943ff73
+    const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
943ff73
+
943ff73
+    if (serverGeneration == 1) {
943ff73
+        linux_parse_vt_settings();
943ff73
 
943ff73
         if (!KeepTty) {
943ff73
             pid_t ppid = getppid();
943ff73
-- 
9d0fee0
2.4.0
943ff73