1 /**[txh]********************************************************************
3 Copyright (c) 2004 by Salvador E. Tropea.
4 Covered by the GPL license.
8 Helper to find a free VT. That's 100% Linux specific.@p
9 The code comes from "lconsole.c" from Allegro project and was originally
10 created by Marek Habersack and then modified by George Foot. I addapted it
11 to my needs and changed license from giftware to GPL.@p
13 ***************************************************************************/
20 #include <sys/ioctl.h>
23 #endif /* __APPLE__ */
27 #if !defined(__linux__)
29 int mi_look_for_free_vt()
34 mi_aux_term *gmi_look_for_free_vt()
43 /**[txh]********************************************************************
46 Look for a free and usable Linux VT. Low level, use
47 @x{gmi_look_for_free_vt}.
49 Return: The VT number or <0 on error.
51 ***************************************************************************/
53 int mi_look_for_free_vt()
54 {/* Code from Allegro. */
55 int tty, console_fd, fd;
60 /* Now we need to find a VT we can use. It must be readable and
61 * writable by us, if we're not setuid root. VT_OPENQRY itself
62 * isn't too useful because it'll only ever come up with one
63 * suggestion, with no guarrantee that we actually have access
66 * At some stage I think this is a candidate for config
67 * file overriding, but for now we'll stat the first N consoles
68 * to see which ones we can write to (hopefully at least one!),
69 * so that we can use that one to do ioctls. We used to use
70 * /dev/console for that purpose but it looks like it's not
71 * always writable by enough people.
73 * Having found and opened a writable device, we query the state
74 * of the first sixteen (fifteen really) consoles, and try
75 * opening each unused one in turn.
78 console_fd=open("/dev/console",O_WRONLY);
82 /* Try some ttys instead... */
85 snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",n);
86 console_fd=open(tty_name,O_WRONLY);
94 /* Get the state of the console -- in particular, the free VT field */
95 if (ioctl(console_fd,VT_GETSTATE,&vts))
99 /* We attempt to set our euid to 0; if we were run with euid 0 to
100 * start with, we'll be able to do this now. Otherwise, we'll just
101 * ignore the error returned since it might not be a problem if the
102 * ttys we look at are owned by the user running the program. */
105 /* tty0 is not really a console, so start counting at 2. */
107 for (tty=1, mask=2; mask; tty++, mask<<=1)
108 if (!(vts.v_state & mask))
110 snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",tty);
111 fd=open(tty_name,O_RDWR);
127 /**[txh]********************************************************************
130 Look for a free and usable Linux VT to be used by the child.
132 Return: A new mi_aux_term structure, you can use @x{gmi_end_aux_term} to
135 ***************************************************************************/
137 mi_aux_term *gmi_look_for_free_vt()
139 int vt=mi_look_for_free_vt();
144 res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
148 asprintf(&res->tty,"/dev/tty%d",vt);