Line 221... |
Line 221... |
terminals[i].xmtrIRQ = IRQ_TERM_0_XMTR + 2 * i;
|
terminals[i].xmtrIRQ = IRQ_TERM_0_XMTR + 2 * i;
|
}
|
}
|
}
|
}
|
|
|
|
|
static int openPty(int *master, int *slave, char *name) {
|
static void makeRaw(int fd) {
|
/* try to open master */
|
struct termios t;
|
strcpy(name, "/dev/ptmx");
|
|
*master = open(name, O_RDWR | O_NONBLOCK);
|
|
if (*master < 0) {
|
|
/* open failed */
|
|
return -1;
|
|
}
|
|
grantpt(*master);
|
|
unlockpt(*master);
|
|
/* master opened, try to open slave */
|
|
strcpy(name, ptsname(*master));
|
|
*slave = open(name, O_RDWR | O_NONBLOCK);
|
|
if (*slave < 0) {
|
|
/* open failed, close master */
|
|
close(*master);
|
|
return -1;
|
|
}
|
|
/* all is well */
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void makeRaw(struct termios *tp) {
|
tcgetattr(fd, &t);
|
tp->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
tp->c_oflag &= ~OPOST;
|
t.c_oflag &= ~OPOST;
|
tp->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
tp->c_cflag &= ~(CSIZE|PARENB);
|
t.c_cflag &= ~(CSIZE|PARENB);
|
tp->c_cflag |= CS8;
|
t.c_cflag |= CS8;
|
|
tcsetattr(fd, TCSANOW, &t);
|
}
|
}
|
|
|
|
|
void termInit(int numTerms) {
|
void termInit(int numTerms, Bool hasTerm[]) {
|
int master, slave;
|
|
char ptyName[100];
|
|
char ptyTitle[100];
|
|
struct termios termios;
|
|
int i;
|
int i;
|
|
int master;
|
|
char slavePath[100];
|
|
int slave;
|
|
char termTitle[100];
|
|
char termSlave[100];
|
|
|
numTerminals = numTerms;
|
numTerminals = numTerms;
|
for (i = 0; i < numTerminals; i++) {
|
for (i = 0; i < numTerminals; i++) {
|
/* open pseudo terminal */
|
/* open pseudo terminal */
|
if (openPty(&master, &slave, ptyName) < 0) {
|
master = open("/dev/ptmx", O_RDWR | O_NONBLOCK);
|
error("cannot open pseudo terminal %d", i);
|
if (master < 0) {
|
}
|
error("cannot open pseudo terminal master for serial line %d", i);
|
|
}
|
|
grantpt(master);
|
|
unlockpt(master);
|
|
strcpy(slavePath, ptsname(master));
|
if (debug) {
|
if (debug) {
|
cPrintf("pseudo terminal '%s': master fd = %d, slave fd = %d\n",
|
cPrintf("pseudo terminal %d: master fd = %d, slave path = '%s'\n",
|
ptyName, master, slave);
|
i, master, slavePath);
|
}
|
}
|
/* set mode to raw */
|
if (hasTerm[i]) {
|
tcgetattr(slave, &termios);
|
/* connect a terminal to the serial line */
|
makeRaw(&termios);
|
/* i.e., fork and exec a new xterm process */
|
tcsetattr(slave, TCSANOW, &termios);
|
|
/* fork and exec a new xterm */
|
|
terminals[i].pid = fork();
|
terminals[i].pid = fork();
|
if (terminals[i].pid < 0) {
|
if (terminals[i].pid < 0) {
|
error("cannot fork xterm process %d", i);
|
error("cannot fork xterm process for serial line %d", i);
|
}
|
}
|
if (terminals[i].pid == 0) {
|
if (terminals[i].pid == 0) {
|
/* terminal process */
|
/* terminal process */
|
setpgid(0, 0);
|
setpgid(0, 0);
|
close(2);
|
|
close(master);
|
close(master);
|
sprintf(ptyName, "-Sab%d", slave);
|
/* open and configure pseudo terminal slave */
|
sprintf(ptyTitle, "ECO32 Terminal %d", i);
|
slave = open(slavePath, O_RDWR | O_NONBLOCK);
|
execlp("xterm", "xterm", "-title", ptyTitle, ptyName, NULL);
|
if (slave < 0) {
|
error("cannot exec xterm process %d", i);
|
error("cannot open pseudo terminal slave '%s'\n", slavePath);
|
|
}
|
|
makeRaw(slave);
|
|
/* exec xterm */
|
|
sprintf(termTitle, "ECO32 Terminal %d", i);
|
|
sprintf(termSlave, "-Sab%d", slave);
|
|
execlp("xterm", "xterm", "-title", termTitle, termSlave, NULL);
|
|
error("cannot exec xterm process for serial line %d", i);
|
|
}
|
|
} else {
|
|
/* leave serial line unconnected */
|
|
terminals[i].pid = 0;
|
|
cPrintf("Serial line %d can be accessed by opening device '%s'.\n",
|
|
i, slavePath);
|
}
|
}
|
fcntl(master, F_SETFL, O_NONBLOCK);
|
fcntl(master, F_SETFL, O_NONBLOCK);
|
terminals[i].in = fdopen(master, "r");
|
terminals[i].in = fdopen(master, "r");
|
setvbuf(terminals[i].in, NULL, _IONBF, 0);
|
setvbuf(terminals[i].in, NULL, _IONBF, 0);
|
terminals[i].out = fdopen(master, "w");
|
terminals[i].out = fdopen(master, "w");
|
setvbuf(terminals[i].out, NULL, _IONBF, 0);
|
setvbuf(terminals[i].out, NULL, _IONBF, 0);
|
|
if (hasTerm[i]) {
|
/* skip the window id written by xterm */
|
/* skip the window id written by xterm */
|
while (fgetc(terminals[i].in) != '\n') ;
|
while (fgetc(terminals[i].in) != '\n') ;
|
}
|
}
|
|
}
|
termReset();
|
termReset();
|
}
|
}
|
|
|
|
|
void termExit(void) {
|
void termExit(void) {
|