View | Details | Raw Unified | Return to bug 434598
Collapse All | Expand All

(-)a/daemon/gdm-server.c (+93 lines)
Lines 33-38 Link Here
33
#include <grp.h>
33
#include <grp.h>
34
#include <signal.h>
34
#include <signal.h>
35
#include <sys/resource.h>
35
#include <sys/resource.h>
36
#include <sys/ioctl.h>
37
#include <sys/vt.h>
36
38
37
#include <glib.h>
39
#include <glib.h>
38
#include <glib/gi18n.h>
40
#include <glib/gi18n.h>
Lines 150-155 _gdm_server_query_ck_for_display_device (GdmServer *server) Link Here
150
        return out;
152
        return out;
151
}
153
}
152
154
155
#ifndef O_NOCTTY
156
# define O_NOCTTY 0
157
#endif
158
159
static int
160
open_vt (int vtno)
161
{
162
	char *vtname;
163
	int fd;
164
165
	vtname = g_strdup_printf ("/dev/tty%d", vtno);
166
167
	do {
168
		errno = 0;
169
		fd = open (vtname, O_RDWR | O_NOCTTY, 0);
170
	} while (errno == EINTR);
171
172
	g_free (vtname);
173
	return fd;
174
}
175
176
static gint
177
find_first_probably_free_vt (void)
178
{
179
	int fd, fdv;
180
	int vtno;
181
	unsigned short vtmask;
182
	struct vt_stat vtstat;
183
	guint v_state;
184
185
	fdv = -1;
186
187
	do {
188
		errno = 0;
189
		fd = open ("/dev/console", O_WRONLY | O_NOCTTY, 0);
190
	} while (errno == EINTR);
191
192
	if (fd >= 0) {
193
		if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0) {
194
			v_state = vtstat.v_state;
195
		} else {
196
			close (fd);
197
			v_state = 0;
198
			fd = -1;
199
		}
200
	} else {
201
		v_state = 0;
202
	}
203
204
	if (fd < 0) {
205
		do {
206
			errno = 0;
207
			fd = open ("/dev/console", O_RDONLY | O_NOCTTY, 0);
208
		} while (errno == EINTR);
209
210
		if (fd >= 0) {
211
			if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0)
212
				v_state = vtstat.v_state;
213
		}
214
	}
215
216
	for (vtno = 7, vtmask = 1 << vtno; vtmask; vtno++, vtmask <<= 1) {
217
		/* Is this console in use? */
218
		if (v_state & vtmask)
219
			continue;
220
221
		/* No, try to open it */
222
		fdv = open_vt (vtno);
223
		if (fdv >= 0)
224
			break;
225
226
		/* If we're here, kernel indicated that the console was free,
227
		 * but we failed to open it. Just go on to higher VTs. */
228
	}
229
230
        if (fdv >= 0)
231
                close (fdv);
232
        else
233
		vtno = -1;
234
235
	if (fd >= 0)
236
		close (fd);
237
238
	return vtno;
239
}
240
153
char *
241
char *
154
gdm_server_get_display_device (GdmServer *server)
242
gdm_server_get_display_device (GdmServer *server)
155
{
243
{
Lines 310-315 gdm_server_resolve_command_line (GdmServer *server, Link Here
310
398
311
        if (vtarg != NULL && ! gotvtarg) {
399
        if (vtarg != NULL && ! gotvtarg) {
312
                argv[len++] = g_strdup (vtarg);
400
                argv[len++] = g_strdup (vtarg);
401
        } else if (!query_in_arglist && !gotvtarg) {
402
                gint vtnum = find_first_probably_free_vt ();
403
404
                if (vtnum > 0)
405
                        argv [len++] = g_strdup_printf ("vt%d", vtnum);
313
        }
406
        }
314
407
315
        argv[len++] = NULL;
408
        argv[len++] = NULL;

Return to bug 434598