31fea01914
OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/gdm?expand=0&rev=c283ea26ca0828e111cc79c54bbc3152
119 lines
2.4 KiB
Diff
119 lines
2.4 KiB
Diff
Index: gdm-2.31.2/daemon/gdm-server.c
|
|
===================================================================
|
|
--- gdm-2.31.2.orig/daemon/gdm-server.c
|
|
+++ gdm-2.31.2/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>
|
|
|
|
#ifdef HAVE_SYS_PRCTL_H
|
|
#include <sys/prctl.h>
|
|
@@ -154,6 +156,92 @@ _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/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)
|
|
{
|
|
@@ -314,6 +402,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;
|