Created
May 11, 2023 18:12
-
-
Save Hodapp87/85c3fadf649f3e20bbc83a9fa5dd554c to your computer and use it in GitHub Desktop.
X11R6 source code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Source: https://www.x.org/releases/X11R6/ | |
// xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c | |
/* $XConsortium: solx86_init.c,v 1.2 94/10/12 20:50:38 kaleb Exp $ */ | |
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c,v 3.0 1994/09/23 10:25:22 dawes Exp $ */ | |
/* | |
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany | |
* Copyright 1993 by David Wexelblat <[email protected]> | |
* | |
* Permission to use, copy, modify, distribute, and sell this software and its | |
* documentation for any purpose is hereby granted without fee, provided that | |
* the above copyright notice appear in all copies and that both that | |
* copyright notice and this permission notice appear in supporting | |
* documentation, and that the names of Thomas Roell and David Wexelblat | |
* not be used in advertising or publicity pertaining to distribution of | |
* the software without specific, written prior permission. Thomas Roell and | |
* David Wexelblat makes no representations about the suitability of this | |
* software for any purpose. It is provided "as is" without express or | |
* implied warranty. | |
* | |
* THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO | |
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
* FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT BE LIABLE FOR | |
* ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER | |
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF | |
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
* | |
*/ | |
#include <signal.h> | |
#include <sys/time.h> | |
#include <unistd.h> | |
#include "X.h" | |
#include "Xmd.h" | |
#include "input.h" | |
#include "scrnintstr.h" | |
#include "compiler.h" | |
#include "xf86.h" | |
#include "xf86Procs.h" | |
#include "xf86_OSlib.h" | |
static Bool KeepTty = FALSE; | |
#ifdef SVR4 | |
static Bool Protect0 = FALSE; | |
#endif | |
static int VTnum = -1; | |
static int xf86StartVT = -1; | |
#define MAX_SECONDS 60 | |
#define USEC_IN_SEC (unsigned long)1000000 | |
int xf86_solx86usleep( | |
#if NeedFunctionPrototypes | |
unsigned long | |
#endif | |
); | |
static void xf86_solx86sleep( | |
#if NeedFunctionPrototypes | |
int | |
#endif | |
); | |
extern void xf86VTRequest( | |
#if NeedFunctionPrototypes | |
int | |
#endif | |
); | |
void xf86OpenConsole() | |
{ | |
int fd; | |
struct vt_mode VT; | |
struct vt_stat vtinfo; | |
char vtname1[10]; | |
int i, FreeVTslot; | |
if (serverGeneration == 1) | |
{ | |
/* check if we're run with euid==0 */ | |
if (geteuid() != 0) | |
{ | |
FatalError("xf86OpenConsole: Server must be suid root\n"); | |
} | |
/* Protect page 0 to help find NULL dereferencing */ | |
/* mprotect() doesn't seem to work */ | |
if (Protect0) | |
{ | |
int fd = -1; | |
if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0) | |
{ | |
ErrorF("xf86OpenConsole: cannot open /dev/zero (%s)\n", | |
strerror(errno)); | |
} | |
else | |
{ | |
if ((int)mmap(0, 0x1000, PROT_NONE, | |
MAP_FIXED | MAP_SHARED, fd, 0) == -1) | |
{ | |
ErrorF("xf86OpenConsole: failed to protect page 0 (%s)\n", | |
strerror(errno)); | |
} | |
close(fd); | |
} | |
} | |
/* | |
* setup the virtual terminal manager | |
*/ | |
if (VTnum != -1) | |
{ | |
xf86Info.vtno = VTnum; | |
} | |
else | |
{ | |
if ((fd = open("/dev/vt00",O_RDWR,0)) < 0) | |
{ | |
FatalError( | |
"xf86OpenConsole: Cannot open /dev/vt00 (%s)\n", | |
strerror(errno)); | |
} | |
if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0) | |
{ | |
FatalError("xf86OpenConsole: Cannot determine current VT\n"); | |
} | |
xf86StartVT=vtinfo.v_active; | |
/* There is a SEVERE problem with x86's VT's the VT_OPENQRY ioctl() | |
* will panic the entire system if all 8 (7 VT's+Console) terminals | |
* are used. | |
* The only other way I've found to determine if there is a free | |
* is to try activating all the the available VT's and see if they | |
* all succeed - if they do, there there is not a free VT, and | |
* the Xserver cannot continue with out panic'ing the system. | |
* (Its ugly, however, it seems to work) | |
* Note there is a possible race condition here, btw. | |
* | |
* David Holland 2/23/94 | |
*/ | |
FreeVTslot = 0; | |
for(i=7; (i>=0) && (!FreeVTslot); i--) | |
if (ioctl(fd, VT_ACTIVATE, i) != 0) | |
FreeVTslot = 1; | |
if(!FreeVTslot) | |
{ | |
FatalError("xf86OpenConsole: Cannot find a free VT\n"); | |
} | |
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) || | |
(xf86Info.vtno == -1)) | |
{ | |
FatalError("xf86OpenConsole: Cannot find a free VT\n"); | |
} | |
close(fd); | |
} | |
ErrorF("(using VT number %d)\n\n", xf86Info.vtno); | |
sprintf(vtname1,"/dev/vt%02d",xf86Info.vtno); /* Solaris 2.1 x86 */ | |
xf86Config(FALSE); /* Read XF86Config */ | |
if (!KeepTty) | |
{ | |
setpgrp(); | |
} | |
if (((xf86Info.consoleFd = open(vtname1, O_RDWR | O_NDELAY, 0)) < 0)) | |
{ | |
FatalError("xf86OpenConsole: Cannot open %s (%s)\n", | |
vtname1, strerror(errno)); | |
} | |
/* change ownership of the vt */ | |
chown(vtname1, getuid(), getgid()); | |
/* | |
* now get the VT | |
*/ | |
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) | |
{ | |
ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n"); | |
} | |
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0) | |
{ | |
ErrorF("xf86OpenConsole: VT_WAITACTIVE failed\n"); | |
} | |
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) | |
{ | |
FatalError("xf86OpenConsole: VT_GETMODE failed\n"); | |
} | |
signal(SIGUSR1, xf86VTRequest); | |
VT.mode = VT_PROCESS; | |
VT.relsig = SIGUSR1; | |
VT.acqsig = SIGUSR1; | |
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0) | |
{ | |
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n"); | |
} | |
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) | |
{ | |
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n"); | |
} | |
} | |
else | |
{ | |
/* serverGeneration != 1 */ | |
/* | |
* now get the VT | |
*/ | |
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) | |
{ | |
ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n"); | |
} | |
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0) | |
{ | |
ErrorF("xf86OpenConsole: VT_WAITACTIVE failed\n"); | |
} | |
/* | |
* If the server doesn't have the VT when the reset occurs, | |
* this is to make sure we don't continue until the activate | |
* signal is received. | |
*/ | |
if (!xf86VTSema) | |
sleep(5); | |
} | |
return; | |
} | |
void xf86CloseConsole() | |
{ | |
struct vt_mode VT; | |
char *console = "/dev/vt00"; | |
int console_fd; | |
/* | |
* Solaris 2.1 x86 doesnt seem to "switch" back to the console | |
* when the VT is relinquished and its mode is reset to auto. | |
* Also, Solaris 2.1 also seems to associate vt00 with the | |
* console so I've opened the "console" back up and made it | |
* the active vt again in text mode and then closed it. | |
* There must be a better hack for this but I'm not aware of | |
* one at this time. | |
* | |
* Doug Anson 11/6/93 | |
* [email protected] | |
* | |
* Fixed - 12/5/93 - David Holland - [email protected] | |
* Did the whole thing similarly to the way linux does it | |
*/ | |
/* reset the display back to text mode */ | |
ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */ | |
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) | |
{ | |
VT.mode = VT_AUTO; | |
ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */ | |
} | |
/* Activate the VT that X was started on */ | |
ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT); | |
close(xf86Info.consoleFd); /* make the vt-manager happy */ | |
return; | |
} | |
int xf86ProcessArgument(argc, argv, i) | |
int argc; | |
char *argv[]; | |
int i; | |
{ | |
/* | |
* Keep server from detaching from controlling tty. This is useful | |
* when debugging (so the server can receive keyboard signals. | |
*/ | |
if (!strcmp(argv[i], "-keeptty")) | |
{ | |
KeepTty = TRUE; | |
return(1); | |
} | |
/* | |
* Undocumented flag to protect page 0 from read/write to help | |
* catch NULL pointer dereferences. This is purely a debugging | |
* flag. | |
*/ | |
if (!strcmp(argv[i], "-protect0")) | |
{ | |
Protect0 = TRUE; | |
return(1); | |
} | |
if ((argv[i][0] == 'v') && (argv[i][1] == 't')) | |
{ | |
if (sscanf(argv[i], "vt%2d", &VTnum) == 0) | |
{ | |
UseMsg(); | |
VTnum = -1; | |
return(0); | |
} | |
return(1); | |
} | |
return(0); | |
} | |
void xf86UseMsg() | |
{ | |
ErrorF("vtXX use the specified VT number\n"); | |
ErrorF("-keeptty "); | |
ErrorF("don't detach controlling tty (for debugging only)\n"); | |
return; | |
} | |
/* | |
* xf86_solx86usleep() - Solaris 2.1 x86 does not have a suitable | |
* replacement (SYSV) for usleep. Although | |
* usleep exists in the BSD compatiblity libs | |
* I dont want to use those libs if possible. | |
* | |
* Doug Anson | |
* [email protected] | |
*/ | |
int xf86_solx86usleep(unsigned long usec) | |
{ | |
int retval = 0; | |
struct itimerval naptime; | |
struct itimerval savetime; | |
unsigned long useconds = 0; | |
unsigned long seconds = 0; | |
int i; | |
unsigned long tmp; | |
/* | |
* WHY DOESN'T THIS SIMPLY DO A select() WITH NO FILE DESCRIPTORS? | |
*/ | |
/* this time will allow a max of MAX_SECONDS seconds sleeping */ | |
for(i=MAX_SECONDS;i>=0;--i) | |
{ | |
tmp = (unsigned long)((unsigned long)(i)*USEC_IN_SEC); | |
if (tmp <= usec) | |
{ | |
seconds = i; | |
if (i == MAX_SECONDS) | |
useconds = 0; | |
else | |
useconds = (unsigned long)(usec - tmp); | |
i = -1; | |
} | |
} | |
/* get the current time */ | |
if ((retval=getitimer(ITIMER_REAL,&savetime)) == 0) | |
{ | |
/* set the itimer to reflect requested time to sleep */ | |
naptime.it_value.tv_sec = savetime.it_value.tv_sec + seconds; | |
naptime.it_value.tv_usec = savetime.it_value.tv_usec + useconds; | |
/* specify a one-shot clock */ | |
naptime.it_interval.tv_usec = 0; | |
naptime.it_interval.tv_sec = 0; | |
/* redisposition SIGALRM */ | |
signal(SIGALRM,xf86_solx86sleep); | |
/* use SIGLARM */ | |
if ((retval=setitimer(ITIMER_REAL,&naptime,NULL)) == 0) | |
/* now just pause */ | |
retval = pause(); | |
/* restore the timer */ | |
retval = setitimer(ITIMER_REAL,&savetime,NULL); | |
/* restore the SIGALRM disposition */ | |
signal(SIGALRM,SIG_DFL); | |
} | |
/* return the return value */ | |
return retval; | |
} | |
/* | |
* xf86_solx86sleep() - This function is a NOP disposition for | |
* the SIGALRM that is used to implement | |
* usleep() in Solaris 2.1 x86. | |
* | |
* Doug Anson | |
* [email protected] | |
*/ | |
static void xf86_solx86sleep(int signo) | |
{ | |
/* do nothing */ | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment