First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / os-support / linux / lnx_init.c
blob4c36b7cf4e12a5faba8b0212a648386fc7857c4a
1 /*
2 * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
3 * Copyright 1993 by David Wexelblat <dwex@goblin.org>
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the names of Orest Zborowski and David Wexelblat
10 * not be used in advertising or publicity pertaining to distribution of
11 * the software without specific, written prior permission. Orest Zborowski
12 * and David Wexelblat make no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without express or
14 * implied warranty.
16 * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
17 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE
19 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 #ifdef HAVE_XORG_CONFIG_H
27 #include <xorg-config.h>
28 #endif
30 #include <X11/X.h>
31 #include <X11/Xmd.h>
33 #include "compiler.h"
35 #include "xf86.h"
36 #include "xf86Priv.h"
37 #include "xf86_OSlib.h"
38 #include "lnx.h"
40 #include <sys/stat.h>
42 #ifdef USE_DEV_FB
43 extern char *getenv(const char *);
44 #include <linux/fb.h>
45 char *fb_dev_name;
46 #endif
48 static Bool KeepTty = FALSE;
49 static int VTnum = -1;
50 static Bool VTSwitch = TRUE;
51 static Bool ShareVTs = FALSE;
52 static int activeVT = -1;
54 static int vtPermSave[4];
55 static char vtname[11];
57 static int
58 saveVtPerms(void)
60 /* We need to use stat to get permissions. */
61 struct stat svtp;
63 /* Do them numerically ordered, hard coded tty0 first. */
64 if (stat("/dev/tty0", &svtp) != 0)
65 return 0;
66 vtPermSave[0] = (int)svtp.st_uid;
67 vtPermSave[1] = (int)svtp.st_gid;
69 /* Now check the console we are dealing with. */
70 if (stat(vtname, &svtp) != 0)
71 return 0;
72 vtPermSave[2] = (int)svtp.st_uid;
73 vtPermSave[3] = (int)svtp.st_gid;
75 return 1;
78 static void
79 restoreVtPerms(void)
81 /* Set the terminal permissions back to before we started. */
82 chown("/dev/tty0", vtPermSave[0], vtPermSave[1]);
83 chown(vtname, vtPermSave[2], vtPermSave[3]);
86 void
87 xf86OpenConsole(void)
89 int i, fd = -1;
90 struct vt_mode VT;
91 struct vt_stat vts;
92 MessageType from = X_PROBED;
93 #ifdef USE_DEV_FB
94 struct fb_var_screeninfo var;
95 int fbfd;
96 #endif
97 char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
98 char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
100 if (serverGeneration == 1) {
102 /* when KeepTty check if we're run with euid==0 */
103 if (KeepTty && geteuid() != 0)
104 FatalError("xf86OpenConsole:"
105 " Server must be suid root for option \"KeepTTY\"\n");
108 * setup the virtual terminal manager
110 if (VTnum != -1) {
111 xf86Info.vtno = VTnum;
112 from = X_CMDLINE;
113 } else {
115 i=0;
116 while (tty0[i] != NULL) {
117 if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
118 break;
119 i++;
122 if (fd < 0)
123 FatalError(
124 "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
125 strerror(errno));
127 if (ShareVTs)
129 if (ioctl(fd, VT_GETSTATE, &vts) == 0)
130 xf86Info.vtno = vts.v_active;
131 else
132 FatalError("xf86OpenConsole: Cannot find the current"
133 " VT (%s)\n", strerror(errno));
134 } else {
135 if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
136 (xf86Info.vtno == -1))
137 FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
138 strerror(errno));
140 close(fd);
143 #ifdef USE_DEV_FB
144 if (!ShareVTs)
146 fb_dev_name=getenv("FRAMEBUFFER");
147 if (!fb_dev_name)
148 fb_dev_name="/dev/fb0current";
150 if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
151 FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
152 fb_dev_name, strerror(errno));
154 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var) < 0)
155 FatalError("xf86OpenConsole: Unable to get screen info %s\n",
156 strerror(errno));
158 #endif
159 xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
161 if (!KeepTty) {
162 pid_t ppid = getppid();
163 pid_t ppgid;
164 ppgid = getpgid(ppid);
167 * change to parent process group that pgid != pid so
168 * that setsid() doesn't fail and we become process
169 * group leader
171 if (setpgid(0,ppgid) < 0)
172 xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
173 strerror(errno));
175 /* become process group leader */
176 if ((setsid() < 0))
177 xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
178 strerror(errno));
181 i=0;
182 while (vcs[i] != NULL) {
183 sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
184 if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
185 break;
186 i++;
189 if (xf86Info.consoleFd < 0)
190 FatalError("xf86OpenConsole: Cannot open virtual console"
191 " %d (%s)\n", xf86Info.vtno, strerror(errno));
193 if (!ShareVTs)
196 * Grab the vt ownership before we overwrite it.
197 * Hard coded /dev/tty0 into this function as well for below.
199 if (!saveVtPerms())
200 xf86Msg(X_WARNING,
201 "xf86OpenConsole: Could not save ownership of VT\n");
203 /* change ownership of the vt */
204 if (chown(vtname, getuid(), getgid()) < 0)
205 xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
206 vtname, strerror(errno));
209 * the current VT device we're running on is not "console", we want
210 * to grab all consoles too
212 * Why is this needed??
214 if (chown("/dev/tty0", getuid(), getgid()) < 0)
215 xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
216 strerror(errno));
220 * Linux doesn't switch to an active vt after the last close of a vt,
221 * so we do this ourselves by remembering which is active now.
223 if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) < 0)
224 xf86Msg(X_WARNING,"xf86OpenConsole: VT_GETSTATE failed: %s\n",
225 strerror(errno));
226 else
227 activeVT = vts.v_active;
229 #if 0
230 if (!KeepTty) {
232 * Detach from the controlling tty to avoid char loss
234 if ((i = open("/dev/tty",O_RDWR)) >= 0) {
235 ioctl(i, TIOCNOTTY, 0);
236 close(i);
239 #endif
241 if (!ShareVTs)
243 #if defined(DO_OS_FONTRESTORE)
244 lnx_savefont();
245 #endif
247 * now get the VT. This _must_ succeed, or else fail completely.
249 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
250 FatalError("xf86OpenConsole: VT_ACTIVATE failed: %s\n",
251 strerror(errno));
253 if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
254 FatalError("xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
255 strerror(errno));
257 if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
258 FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
259 strerror(errno));
261 signal(SIGUSR1, xf86VTRequest);
263 VT.mode = VT_PROCESS;
264 VT.relsig = SIGUSR1;
265 VT.acqsig = SIGUSR1;
267 if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
268 FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
269 strerror(errno));
271 if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
272 FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
273 strerror(errno));
275 /* we really should have a InitOSInputDevices() function instead
276 * of Init?$#*&Device(). So I just place it here */
278 #ifdef USE_DEV_FB
279 /* copy info to new console */
280 var.yoffset=0;
281 var.xoffset=0;
282 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
283 FatalError("Unable to set screen info\n");
284 close(fbfd);
285 #endif
286 } else { /* ShareVTs */
287 close(xf86Info.consoleFd);
289 signal(SIGUSR2, xf86ReloadInputDevs);
290 } else { /* serverGeneration != 1 */
291 if (!ShareVTs && VTSwitch)
294 * now get the VT
296 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
297 xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
298 strerror(errno));
301 if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
302 xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
303 strerror(errno));
305 return;
308 void
309 xf86CloseConsole()
311 struct vt_mode VT;
312 #if defined(DO_OS_FONTRESTORE)
313 struct vt_stat vts;
314 int vtno = -1;
315 #endif
317 if (ShareVTs) return;
319 #if defined(DO_OS_FONTRESTORE)
320 if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) < 0)
321 xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETSTATE failed: %s\n",
322 strerror(errno));
323 else
324 vtno = vts.v_active;
325 #endif
327 /* Back to text mode ... */
328 if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT) < 0)
329 xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n",
330 strerror(errno));
332 if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
333 xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n",
334 strerror(errno));
335 else {
336 /* set dflt vt handling */
337 VT.mode = VT_AUTO;
338 if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
339 xf86Msg(X_WARNING, "xf86CloseConsole: VT_SETMODE failed: %s\n",
340 strerror(errno));
343 if (VTSwitch)
346 * Perform a switch back to the active VT when we were started
348 if (activeVT >= 0) {
349 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT) < 0)
350 xf86Msg(X_WARNING, "xf86CloseConsole: VT_ACTIVATE failed: %s\n",
351 strerror(errno));
352 if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, activeVT) < 0)
353 xf86Msg(X_WARNING,
354 "xf86CloseConsole: VT_WAITACTIVE failed: %s\n",
355 strerror(errno));
356 activeVT = -1;
359 #if defined(DO_OS_FONTRESTORE)
360 if (xf86Info.vtno == vtno) /* check if we are active */
361 lnx_restorefont();
362 lnx_freefontdata();
363 #endif
365 close(xf86Info.consoleFd); /* make the vt-manager happy */
367 restoreVtPerms(); /* restore the permissions */
369 return;
373 xf86ProcessArgument(int argc, char *argv[], int i)
376 * Keep server from detaching from controlling tty. This is useful
377 * when debugging (so the server can receive keyboard signals.
379 if (!strcmp(argv[i], "-keeptty"))
381 KeepTty = TRUE;
382 return(1);
384 if (!strcmp(argv[i], "-novtswitch"))
386 VTSwitch = FALSE;
387 return(1);
389 if (!strcmp(argv[i], "-sharevts"))
391 ShareVTs = TRUE;
392 return(1);
394 if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
396 if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
398 UseMsg();
399 VTnum = -1;
400 return(0);
402 return(1);
404 return(0);
407 void
408 xf86UseMsg()
410 ErrorF("vtXX use the specified VT number\n");
411 ErrorF("-keeptty ");
412 ErrorF("don't detach controlling tty (for debugging only)\n");
413 ErrorF("-novtswitch don't immediately switch to new VT\n");
414 ErrorF("-sharevts share VTs with another X server\n");
415 return;