blob: 3fc79fd42c59db52bc922b04584fc4a770e5a764 [file] [log] [blame]
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sched.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include "stdio_console.h"
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
void stdio_write(int fd, const char *string, int len)
{
static int need_cr = 0;
int i;
for(i=0;i<len;i++){
if(*string == '\n') need_cr = 1;
else if(need_cr){
if(*string != '\r') write(fd, "\r", 1);
need_cr = 0;
}
write(fd, string++, 1);
}
}
void stdio_rcv_proc(int fd)
{
int n;
char ch;
while((n = read(fd, &ch, sizeof(ch))) == sizeof(ch)){
stdio_receive_char(fd, ch);
}
if((n < 0) && (errno != EAGAIN))
printk("stdio_rcv_proc read failed, errno = %d\n", errno);
enable_fd(fd);
}
void setup_fd(int fd)
{
struct termios tt;
unsigned long flags;
flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
flags &= ~O_ASYNC;
if(fcntl(fd, F_SETFL, flags) < 0){
perror("fcntl setting flags");
return;
}
tcgetattr(fd, &tt);
cfmakeraw(&tt);
if(tcsetattr(fd, TCSADRAIN, &tt) < 0){
printk("tcsetattr failed, errno = %d\n", errno);
panic("stdio receive thread couldn't set fd raw");
}
}
struct xterm_info {
char tty[2];
int fd;
int console_num;
int *pid_out;
};
static void xterm_tramp(void *arg)
{
struct xterm_info *info;
int pid;
char title[sizeof("Virtual Console nn\0")], flag[sizeof("Sxxnn\0")];
info = arg;
sprintf(flag, "-S%c%c%d", info->tty[0], info->tty[1], info->fd);
sprintf(title, "Virtual Console %d", info->console_num);
if((pid = fork()) != 0) *info->pid_out = pid;
else {
execlp("xterm", "xterm", flag, "-T", title, NULL);
exit(1);
}
}
int open_vt(int n, int *pid_out)
{
struct xterm_info info;
int master, slave;
char dev[] = "/dev/ptyXX", c;
master = getmaster(dev);
dev[strlen("/dev/")] = 't';
slave = open(dev, O_RDWR);
if(slave != -1){
info.tty[0] = dev[strlen("/dev/pty")];
info.tty[1] = dev[strlen("/dev/ptyX")];
info.fd = master;
info.console_num = n;
info.pid_out = pid_out;
input_cb(xterm_tramp, &info, sizeof(info));
while((read(slave, &c, sizeof(c)) == sizeof(c)) && (c != '\n')) ;
}
setup_fd(slave);
return(slave);
}