aboutsummaryrefslogtreecommitdiff
path: root/src/monkey/get_free_vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/monkey/get_free_vt.c')
-rw-r--r--src/monkey/get_free_vt.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/monkey/get_free_vt.c b/src/monkey/get_free_vt.c
new file mode 100644
index 000000000..f5c980005
--- /dev/null
+++ b/src/monkey/get_free_vt.c
@@ -0,0 +1,153 @@
1/**[txh]********************************************************************
2
3 Copyright (c) 2004 by Salvador E. Tropea.
4 Covered by the GPL license.
5
6 Module: Linux VT.
7 Comments:
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
10created by Marek Habersack and then modified by George Foot. I addapted it
11to my needs and changed license from giftware to GPL.@p
12
13***************************************************************************/
14
15#define _GNU_SOURCE
16#include <string.h>
17#include <stdio.h>
18#include <unistd.h>
19#include <fcntl.h>
20#include <sys/ioctl.h>
21#ifdef __APPLE__
22#include <util.h>
23#endif /* __APPLE__ */
24
25#include "mi_gdb.h"
26
27#if !defined(__linux__)
28
29int mi_look_for_free_vt()
30{
31 return -1;
32}
33
34mi_aux_term *gmi_look_for_free_vt()
35{
36 return NULL;
37}
38
39#else
40
41#include <linux/vt.h>
42
43/**[txh]********************************************************************
44
45 Description:
46 Look for a free and usable Linux VT. Low level, use
47@x{gmi_look_for_free_vt}.
48
49 Return: The VT number or <0 on error.
50
51***************************************************************************/
52
53int mi_look_for_free_vt()
54{/* Code from Allegro. */
55 int tty, console_fd, fd;
56 unsigned short mask;
57 char tty_name[16];
58 struct vt_stat vts;
59
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
64 * to it.
65 *
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.
72 *
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.
76 */
77
78 console_fd=open("/dev/console",O_WRONLY);
79 if (console_fd<0)
80 {
81 int n;
82 /* Try some ttys instead... */
83 for (n=1; n<=24; n++)
84 {
85 snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",n);
86 console_fd=open(tty_name,O_WRONLY);
87 if (console_fd>=0)
88 break;
89 }
90 if (n>24)
91 return -1;
92 }
93
94 /* Get the state of the console -- in particular, the free VT field */
95 if (ioctl(console_fd,VT_GETSTATE,&vts))
96 return -2;
97 close(console_fd);
98
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. */
103 seteuid(0);
104
105 /* tty0 is not really a console, so start counting at 2. */
106 fd=-1;
107 for (tty=1, mask=2; mask; tty++, mask<<=1)
108 if (!(vts.v_state & mask))
109 {
110 snprintf(tty_name,sizeof(tty_name),"/dev/tty%d",tty);
111 fd=open(tty_name,O_RDWR);
112 if (fd!=-1)
113 {
114 close(fd);
115 break;
116 }
117 }
118
119 seteuid(getuid());
120
121 if (!mask)
122 return -3;
123
124 return tty;
125}
126
127/**[txh]********************************************************************
128
129 Description:
130 Look for a free and usable Linux VT to be used by the child.
131
132 Return: A new mi_aux_term structure, you can use @x{gmi_end_aux_term} to
133release it.
134
135***************************************************************************/
136
137mi_aux_term *gmi_look_for_free_vt()
138{
139 int vt=mi_look_for_free_vt();
140 mi_aux_term *res;
141
142 if (vt<0)
143 return NULL;
144 res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
145 if (!res)
146 return NULL;
147 res->pid=-1;
148 asprintf(&res->tty,"/dev/tty%d",vt);
149 return res;
150}
151
152#endif
153