1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#include "config.h"
#include <libgnome/libgnome.h>
#include "gdm.h"
#include "misc.h"
#include "getvt.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
extern int GdmFirstVT;
extern gboolean GdmVTAllocation;
#ifdef __linux__
#include <sys/vt.h>
static int
open_vt (int vtno)
{
char *vtname = g_strdup_printf ("/dev/tty%d", vtno);
int fd = open (vtname, O_RDWR);
g_free (vtname);
return fd;
}
static int
get_free_vt (int *vtfd)
{
int fd, fdv;
int vtno;
GList *to_close_vts = NULL, *li;
*vtfd = -1;
fd = open ("/dev/console", O_WRONLY, 0);
if (fd < 0)
return -1;
if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) {
close (fd);
return -1;
}
fdv = open_vt (vtno);
if (fdv < 0) {
close (fd);
return -1;
}
while (vtno < GdmFirstVT) {
int oldvt = vtno;
to_close_vts = g_list_prepend (to_close_vts,
GINT_TO_POINTER (fdv));
if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) {
vtno = -1;
goto cleanup;
}
if (oldvt == vtno) {
vtno = -1;
goto cleanup;
}
fdv = open_vt (vtno);
if (fdv < 0) {
vtno = -1;
goto cleanup;
}
}
*vtfd = fdv;
cleanup:
for (li = to_close_vts; li != NULL; li = li->next) {
close (GPOINTER_TO_INT (li->data));
}
return vtno;
}
char *
gdm_get_empty_vt_argument (int *fd, int *vt)
{
if ( ! GdmVTAllocation) {
*fd = -1;
return NULL;
}
*vt = get_free_vt (fd);
if (*vt < 0)
return NULL;
else
return g_strdup_printf ("vt%d", *vt);
}
#else /* here this is just a stub, we don't know how to do this outside
of linux really */
char *
gdm_get_empty_vt_argument (int *fd, int *vt)
{
*fd = -1;
*vt = -1;
return NULL;
}
#endif
|