File gdm-vt-allocation-hack.patch of Package gdm.16051

diff -Npur gdm-3.10.0.1/daemon/gdm-server.c gdm-3.10.0.1-new/daemon/gdm-server.c
--- gdm-3.10.0.1/daemon/gdm-server.c	2013-09-19 09:53:23.000000000 +0800
+++ gdm-3.10.0.1-new/daemon/gdm-server.c	2014-07-01 09:40:33.295385944 +0800
@@ -33,6 +33,7 @@
 #include <grp.h>
 #include <signal.h>
 #include <sys/ioctl.h>
+#include <sys/vt.h>
 #include <sys/resource.h>
 
 #ifdef HAVE_SYS_PRCTL_H
@@ -165,6 +166,91 @@ _gdm_server_query_ck_for_display_device
         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/tty0", 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/tty0", 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 = atoi(GDM_INITIAL_VT), 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)
 {
@@ -362,6 +448,11 @@ gdm_server_resolve_command_line (GdmServ
 
         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;