#include "X.h"
#include "Xmd.h"
#include "compiler.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
static Bool KeepTty = FALSE;
static int VTnum = -1;
static char *vtdevice = NULL;
static int sco_console_mode = -1;
extern Bool mpxLock;
void
xf86OpenConsole()
{
int fd,i, ioctl_ret;
struct vt_mode VT;
static char vtname[32];
struct vid_info vidinf;
struct sigaction sigvtsw;
if (serverGeneration == 1) {
if (geteuid() != 0) {
FatalError("xf86OpenConsole: Server must be setuid root\n");
}
if (VTnum == -1) {
char *ttn;
vidinf.size = sizeof(vidinf);
if (ioctl (0, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: Not on a console device "
"or error querying device (%s)\n", strerror (errno));
}
VTnum = vidinf.m_num + 1;
ttn = ttyname (0);
if (ttn == (char *)0) {
ErrorF ("xf86OpenConsole: Error determining TTY name (%s)\n",
strerror(errno));
snprintf (vtname, sizeof(vtname)-1, "/dev/tty%02d", VTnum);
} else {
strlcpy (vtname, ttn, sizeof(vtname));
}
vtdevice = vtname;
} else if (VTnum == -2 || VTnum >= 0) {
if (VTnum != -2) {
snprintf (vtname, sizeof(vtname)-1, "/dev/tty%02d", VTnum);
vtdevice = vtname;
}
fd = open (vtdevice, O_RDWR | O_NDELAY, 0);
if (fd < 0) {
FatalError ("xf86OpenConsole: Can not open device '%s' (%s)\n",
vtdevice, strerror(errno));
}
vidinf.size = sizeof(vidinf);
if (ioctl (fd, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: '%s' is not a console device "
"or error querying device (%s)\n", vtname, strerror (errno));
}
VTnum = vidinf.m_num + 1;
close (fd);
}
ErrorF("(using VT%02d device %s)\n\n", VTnum, vtdevice);
if ((xf86Info.consoleFd = open(vtdevice, O_RDWR | O_NDELAY, 0)) < 0) {
FatalError("xf86OpenConsole: Cannot open %s (%s)\n", vtdevice,
strerror(errno));
}
if (freopen(vtdevice, "r+", stdin) == (FILE *) NULL) {
FatalError("xf86OpenConsole: Cannot reopen stdin as %s (%s)\n",
vtdevice, strerror(errno));
}
if (freopen(vtname, "r+", stdout) == (FILE *) NULL) {
FatalError("xf86OpenConsole: Cannot reopen stdout as %s (%s)\n",
vtdevice, strerror(errno));
}
vidinf.size = sizeof(vidinf);
if (ioctl (xf86Info.consoleFd, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: Failed to query console number (%s)\n",
strerror (errno));
}
xf86Info.vtno = vidinf.m_num;
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) {
ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno));
}
if (!KeepTty) {
setpgrp();
}
if ((sco_console_mode = ioctl(xf86Info.consoleFd, CONS_GET, 0L)) < 0) {
FatalError("xf86OpenConsole: CONS_GET failed on console (%s)\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) {
FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n", strerror(errno));
}
sigvtsw.sa_handler = xf86VTRequest;
sigfillset(&sigvtsw.sa_mask);
sigvtsw.sa_flags = 0;
sigaction(SIGUSR1, &sigvtsw, NULL);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.frsig = SIGINT;
VT.waitv = 0;
ioctl_ret = 0;
for (i = 0; i < 5; i++) {
ioctl_ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
if (ioctl_ret >= 0)
break;
usleep(999999);
}
if (ioctl_ret < 0) {
FatalError("xf86OpenConsole: VT_SETMODE failed (%s)\n", strerror(errno));
}
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) {
ErrorF("Failed to set graphics mode (%s)\n", strerror(errno));
}
} else {
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) {
ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno));
}
}
}
void
xf86CloseConsole()
{
struct vt_mode VT;
struct sigaction sigvtsw;
ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT0);
if (sco_console_mode != -1) {
ioctl(xf86Info.consoleFd, MODESWITCH | sco_console_mode, 0L);
}
ioctl(xf86Info.consoleFd, VT_RELDISP, 1);
sigvtsw.sa_handler = SIG_DFL;
sigfillset(&sigvtsw.sa_mask);
sigvtsw.sa_flags = 0;
sigaction(SIGUSR1, &sigvtsw, NULL);
VT.mode = VT_AUTO;
VT.waitv = 0;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.frsig = SIGINT;
ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
close(xf86Info.consoleFd);
}
int
xf86ProcessArgument(int argc, char *argv[], int i)
{
if (!strcmp(argv[i], "-keeptty")) {
KeepTty = TRUE;
return(1);
}
if (!strcmp(argv[i], "-nompxlock")) {
mpxLock = FALSE;
return (1);
}
if ((argv[i][0] == 'v') && (argv[i][1] == 't')) {
if (sscanf(argv[i], "vt%2d", &VTnum) == 0) {
UseMsg();
VTnum = -1;
return(0);
}
if (VTnum <= 0) {
UseMsg();
VTnum = -1;
return(0);
}
return(1);
}
if (!strcmp(argv[i], "-crt")) {
if (++i > argc) {
UseMsg();
VTnum = -1;
return(0);
} else {
VTnum = -2;
vtdevice = argv[i];
return(2);
}
}
return(0);
}
void
xf86UseMsg()
{
ErrorF("vtXX use the specified VT number\n");
ErrorF("-crt DEVICE use the specified VT device\n");
ErrorF("-nompxlock dont bind X server to CPU 0\n");
ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n");
}