summaryrefslogtreecommitdiffstats
path: root/gdm/gdm-vt-allocation-hack.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gdm/gdm-vt-allocation-hack.patch')
-rw-r--r--gdm/gdm-vt-allocation-hack.patch118
1 files changed, 118 insertions, 0 deletions
diff --git a/gdm/gdm-vt-allocation-hack.patch b/gdm/gdm-vt-allocation-hack.patch
new file mode 100644
index 0000000..56fa5a1
--- /dev/null
+++ b/gdm/gdm-vt-allocation-hack.patch
@@ -0,0 +1,118 @@
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 39def47..03488fd 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -33,6 +33,8 @@
+ #include <grp.h>
+ #include <signal.h>
+ #include <sys/resource.h>
++#include <sys/ioctl.h>
++#include <sys/vt.h>
+
+ #include <glib.h>
+ #include <glib/gi18n.h>
+@@ -150,6 +152,92 @@ _gdm_server_query_ck_for_display_device (GdmServer *server)
+ return out;
+ }
+
++#ifndef O_NOCTTY
++# define O_NOCTTY 0
++#endif
++
++static int
++open_vt (int vtno)
++{
++ char *vtname;
++ int fd;
++
++ vtname = g_strdup_printf ("/dev/tty%d", vtno);
++
++ do {
++ errno = 0;
++ fd = open (vtname, O_RDWR | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ g_free (vtname);
++ return fd;
++}
++
++static gint
++find_first_probably_free_vt (void)
++{
++ int fd, fdv;
++ int vtno;
++ unsigned short vtmask;
++ struct vt_stat vtstat;
++ guint v_state;
++
++ fdv = -1;
++
++ do {
++ errno = 0;
++ fd = open ("/dev/console", O_WRONLY | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ if (fd >= 0) {
++ if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0) {
++ v_state = vtstat.v_state;
++ } else {
++ close (fd);
++ v_state = 0;
++ fd = -1;
++ }
++ } else {
++ v_state = 0;
++ }
++
++ if (fd < 0) {
++ do {
++ errno = 0;
++ fd = open ("/dev/console", O_RDONLY | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ if (fd >= 0) {
++ if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0)
++ v_state = vtstat.v_state;
++ }
++ }
++
++ for (vtno = 7, vtmask = 1 << vtno; vtmask; vtno++, vtmask <<= 1) {
++ /* Is this console in use? */
++ if (v_state & vtmask)
++ continue;
++
++ /* No, try to open it */
++ fdv = open_vt (vtno);
++ if (fdv >= 0)
++ break;
++
++ /* If we're here, kernel indicated that the console was free,
++ * but we failed to open it. Just go on to higher VTs. */
++ }
++
++ if (fdv >= 0)
++ close (fdv);
++ else
++ vtno = -1;
++
++ if (fd >= 0)
++ close (fd);
++
++ return vtno;
++}
++
+ char *
+ gdm_server_get_display_device (GdmServer *server)
+ {
+@@ -310,6 +398,11 @@ gdm_server_resolve_command_line (GdmServer *server,
+
+ if (vtarg != NULL && ! gotvtarg) {
+ argv[len++] = g_strdup (vtarg);
++ } else if (!query_in_arglist && !gotvtarg) {
++ gint vtnum = find_first_probably_free_vt ();
++
++ if (vtnum > 0)
++ argv [len++] = g_strdup_printf ("vt%d", vtnum);
+ }
+
+ argv[len++] = NULL;