|
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; |