1 |
nirbheek 11/05/03 06:46:10 |
2 |
|
3 |
Added: gdm-2.32.0-fix-vt-problems.patch |
4 |
Log: |
5 |
Fix bug 288852, vt detection finally works properly, remove old |
6 |
|
7 |
(Portage version: 2.1.9.46/cvs/Linux x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: gdm-2.32.0-fix-vt-problems.patch |
16 |
=================================================================== |
17 |
From 64002e623fea54ab10040206d164c5fdee4a43d2 Mon Sep 17 00:00:00 2001 |
18 |
From: Nirbheek Chauhan <nirbheek@g.o> |
19 |
Date: Fri, 15 Apr 2011 22:13:44 +0530 |
20 |
Subject: [PATCH] Fix VT grab race with getty causing X to grab the wrong VT |
21 |
|
22 |
On bootup, if X is spawned without any args, it'll take up the first unused VT. |
23 |
If GDM starts up before gettys are spawned, X takes up VT1 or VT2 depending on |
24 |
the init system and bootsplash. |
25 |
|
26 |
This is problematic because afterwards getty will come up underneath X, and |
27 |
cause keyboard problems and eventually crash X. |
28 |
|
29 |
So we read /etc/inittab, check for open VTs, compare the two values, and take |
30 |
the conservative one. |
31 |
--- |
32 |
configure.ac | 4 ++ |
33 |
daemon/Makefile.am | 1 + |
34 |
daemon/gdm-server.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++- |
35 |
3 files changed, 110 insertions(+), 1 deletions(-) |
36 |
|
37 |
diff --git a/configure.ac b/configure.ac |
38 |
index ca0f8bb..b9e7462 100644 |
39 |
--- a/configure.ac |
40 |
+++ b/configure.ac |
41 |
@@ -302,6 +302,10 @@ AC_CHECK_TYPE(socklen_t,, |
42 |
AC_CHECK_HEADERS(sys/sockio.h) |
43 |
AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv]) |
44 |
|
45 |
+dnl Needed for querying the kernel for free VTs |
46 |
+AC_CHECK_HEADERS(sys/vt.h) |
47 |
+AC_CHECK_HEADERS(sys/ioctl.h) |
48 |
+ |
49 |
dnl checks needed for Darwin compatibility to linux **environ. |
50 |
AC_CHECK_HEADERS(crt_externs.h) |
51 |
AC_CHECK_FUNCS(_NSGetEnviron) |
52 |
diff --git a/daemon/Makefile.am b/daemon/Makefile.am |
53 |
index da18835..c1b6bda 100644 |
54 |
--- a/daemon/Makefile.am |
55 |
+++ b/daemon/Makefile.am |
56 |
@@ -14,6 +14,7 @@ AM_CPPFLAGS = \ |
57 |
-DLIBEXECDIR=\"$(libexecdir)\" \ |
58 |
-DLOGDIR=\"$(logdir)\" \ |
59 |
-DSBINDIR=\"$(sbindir)\" \ |
60 |
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \ |
61 |
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ |
62 |
-DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ |
63 |
-DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ |
64 |
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c |
65 |
index 339f3cc..29d16dc 100644 |
66 |
--- a/daemon/gdm-server.c |
67 |
+++ b/daemon/gdm-server.c |
68 |
@@ -26,6 +26,8 @@ |
69 |
#include <unistd.h> |
70 |
#include <string.h> |
71 |
#include <sys/types.h> |
72 |
+#include <sys/ioctl.h> |
73 |
+#include <sys/vt.h> |
74 |
#include <sys/wait.h> |
75 |
#include <errno.h> |
76 |
#include <ctype.h> |
77 |
@@ -42,6 +44,7 @@ |
78 |
#include <glib/gi18n.h> |
79 |
#include <glib/gstdio.h> |
80 |
#include <glib-object.h> |
81 |
+#include <gio/gio.h> |
82 |
|
83 |
#include <X11/Xlib.h> /* for Display */ |
84 |
|
85 |
@@ -54,6 +57,8 @@ extern char **environ; |
86 |
|
87 |
#define GDM_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SERVER, GdmServerPrivate)) |
88 |
|
89 |
+#define INITTAB SYSCONFDIR"/inittab" |
90 |
+ |
91 |
/* These are the servstat values, also used as server |
92 |
* process exit codes */ |
93 |
#define SERVER_TIMEOUT 2 /* Server didn't start */ |
94 |
@@ -674,6 +679,105 @@ gdm_server_spawn (GdmServer *server, |
95 |
} |
96 |
|
97 |
/** |
98 |
+ * Parse the inittab file used by getty to spawn VTs to find unused ttys |
99 |
+ */ |
100 |
+int |
101 |
+get_free_vt_from_inittab () |
102 |
+{ |
103 |
+ GFile *gfile; |
104 |
+ GFileInputStream *contents; |
105 |
+ GDataInputStream *dstream; |
106 |
+ GRegex *getty; |
107 |
+ GMatchInfo *tty_match = NULL; |
108 |
+ GSList *tty_list = NULL; |
109 |
+ GError *error = NULL; |
110 |
+ gchar *temp = NULL; |
111 |
+ int vtno = 0; |
112 |
+ |
113 |
+ gfile = g_file_new_for_path (INITTAB); |
114 |
+ contents = g_file_read (gfile, NULL, &error); |
115 |
+ g_object_unref (gfile); |
116 |
+ if (!contents) { |
117 |
+ if (error) { |
118 |
+ g_debug ("Unable to open file %s", INITTAB); |
119 |
+ g_error_free (error); |
120 |
+ } |
121 |
+ goto out; |
122 |
+ } |
123 |
+ |
124 |
+ dstream = g_data_input_stream_new (G_INPUT_STREAM (contents)); |
125 |
+ getty = g_regex_new ("^c[0-9]+:.+getty.+tty([0-9]+)", 0, 0, NULL); |
126 |
+ g_object_unref (contents); |
127 |
+ |
128 |
+ while (1) { |
129 |
+ temp = g_data_input_stream_read_line (dstream, NULL, NULL, &error); |
130 |
+ if (!temp) |
131 |
+ break; |
132 |
+ if (!g_regex_match (getty, temp, 0, &tty_match)) |
133 |
+ continue; |
134 |
+ g_free (temp); |
135 |
+ temp = g_match_info_fetch (tty_match, 1); |
136 |
+ if (!temp) |
137 |
+ continue; |
138 |
+ tty_list = g_slist_insert_sorted (tty_list, temp, (GCompareFunc)g_strcmp0); |
139 |
+ g_match_info_free (tty_match); |
140 |
+ } |
141 |
+ |
142 |
+ if (error) { |
143 |
+ g_debug ("Unable to read line from %s", INITTAB); |
144 |
+ g_error_free (error); |
145 |
+ goto free; |
146 |
+ } |
147 |
+ |
148 |
+ /* Ignore holes in vt allocation, just take the last one */ |
149 |
+ temp = g_slist_last (tty_list)->data; |
150 |
+ if (temp) |
151 |
+ vtno = (int) g_ascii_strtoull (temp, NULL, 10) + 1; |
152 |
+ |
153 |
+free: |
154 |
+ g_object_unref (dstream); |
155 |
+ g_regex_unref (getty); |
156 |
+ g_slist_free_full (tty_list, g_free); |
157 |
+ g_free (error); |
158 |
+out: |
159 |
+ return vtno; |
160 |
+} |
161 |
+ |
162 |
+/** |
163 |
+ * Query the VT_* kernel ioctls to find an empty tty |
164 |
+ */ |
165 |
+int |
166 |
+get_free_vt_from_kernel() |
167 |
+{ |
168 |
+ int fd, vtno = 0; |
169 |
+ |
170 |
+ fd = open ("/dev/tty0", O_WRONLY, 0); |
171 |
+ if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) { |
172 |
+ vtno = 0; |
173 |
+ g_debug ("Unable to find a free vt, falling back to Xorg autodetect"); |
174 |
+ } |
175 |
+ return vtno; |
176 |
+} |
177 |
+ |
178 |
+gchar* |
179 |
+get_free_vt () |
180 |
+{ |
181 |
+ int inittab_vtno, kernel_vtno; |
182 |
+ gchar* vt = NULL; |
183 |
+ |
184 |
+ inittab_vtno = get_free_vt_from_inittab(); |
185 |
+ if (inittab_vtno > 0) |
186 |
+ g_debug ("Inittab says vt%i is free\n", inittab_vtno); |
187 |
+ kernel_vtno = get_free_vt_from_kernel(); |
188 |
+ if (kernel_vtno > 0) |
189 |
+ g_debug ("Kernel says vt%i is free\n", kernel_vtno); |
190 |
+ /* Select the greater of the two because getty will use the others */ |
191 |
+ if (kernel_vtno != 0 && inittab_vtno != 0) |
192 |
+ vt = g_strdup_printf ("vt%i", kernel_vtno > inittab_vtno ? kernel_vtno : inittab_vtno); |
193 |
+ return vt; |
194 |
+} |
195 |
+ |
196 |
+/** |
197 |
* gdm_server_start: |
198 |
* @disp: Pointer to a GdmDisplay structure |
199 |
* |
200 |
@@ -686,7 +790,7 @@ gdm_server_start (GdmServer *server) |
201 |
gboolean res; |
202 |
|
203 |
/* fork X server process */ |
204 |
- res = gdm_server_spawn (server, NULL); |
205 |
+ res = gdm_server_spawn (server, get_free_vt()); |
206 |
|
207 |
return res; |
208 |
} |
209 |
-- |
210 |
1.7.3.4 |