TODO: still not 100% compatible

make it more equal with the original SYSIII Source without changing the resulting
object
This commit is contained in:
Oliver Lehmann 2008-05-07 20:09:24 +00:00
parent 53c4caf537
commit c66286adb4
1 changed files with 257 additions and 206 deletions

View File

@ -11,6 +11,10 @@
*************************************************************************** ***************************************************************************
**************************************************************************/ **************************************************************************/
/*
* general TTY subroutines
*/
#include <sys/param.h> #include <sys/param.h>
#include <sys/state.h> #include <sys/state.h>
#include <sys/conf.h> #include <sys/conf.h>
@ -21,169 +25,194 @@
#include <sys/ttold.h> #include <sys/ttold.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/sysparm.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/inode.h> #include <sys/inode.h>
#include <sys/mmu.h> #include <sys/mmu.h>
#include <sys/s.out.h> #include <sys/s.out.h>
#include <sys/user.h> #include <sys/user.h>
#define CDEF (CLOCAL | PARODD | PARENB | CREAD | CSTOPB)
#define CDEF1 (CLOCAL | PARENB | CREAD | CSTOPB)
char ttywstr[] = "@[$]tty.c Rev : 4.2+ 02/07/84 13:50:59"; char ttywstr[] = "@[$]tty.c Rev : 4.2+ 02/07/84 13:50:59";
extern int Canbsiz; extern int Canbsiz;
char canonb[256];
extern int numterm; extern int numterm;
int tthiwat[] = {
0,
60, 60, 60, 60, 60, 60,
120, 120, 180, 180, 240, 240, /*
240, 100, 100 * tty low and high water marks
* high < TTYHOG
*/
int tthiwat[16] = {
0, 60, 60, 60,
60, 60, 60, 120,
120, 180, 180, 240,
240, 240, 100, 100,
}; };
int ttlowat[] = { int ttlowat[16] = {
0, 20, 20, 20,
20, 20, 20, 40,
40, 60, 60, 80,
80, 80, 50, 50,
};
char ttcchar[NCC] = {
CINTR,
CQUIT,
CERASE,
CKILL,
CEOF,
0, 0,
20, 20, 20, 20, 20, 20, 0,
40, 40, 60, 60, 80, 80, 0
80, 50, 50
}; };
char ttcchar[NCC] = {
CINTR, CQUIT, CERASE, CKILL, CEOF };
static int noterm; static int noterm;
char maptab[] ={ /* canon buffer */
0, 0, 0, 0, 0, 0, 0, 0, char canonb[256];
0, 0, 0, 0, 0, 0, 0, 0, /*
0, 0, 0, 0, 0, 0, 0, 0, * Input mapping table-- if an entry is non-zero, when the
0, 0, 0, 0, 0, 0, 0, 0, * corresponding character is typed preceded by "\" the escape
0, '|', 0, 0, 0, 0, 0, '`', * sequence is replaced by the table value. Mostly used for
'{', '}', 0, 0, 0, 0, 0, 0, * upper-case only terminals.
0, 0, 0, 0, 0, 0, 0, 0, */
0, 0, 0, 0, 0, 0, 0, 0, char maptab[] ={
0, 0, 0, 0, 0, 0, 0, 0, 000,000,000,000,000,000,000,000,
0, 0, 0, 0, 0, 0, 0, 0, 000,000,000,000,000,000,000,000,
0, 0, 0, 0, 0, 0, 0, 0, 000,000,000,000,000,000,000,000,
0, 0, 0, 0, 0, 0, '~', 0, 000,000,000,000,000,000,000,000,
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 000,'|',000,000,000,000,000,'`',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', '{','}',000,000,000,000,000,000,
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 000,000,000,000,000,000,000,000,
'X', 'Y', 'Z', 0, 0, 0, 0, 0, 000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,'~',000,
000,'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W',
'X','Y','Z',000,000,000,000,000,
}; };
/*
* routine called on first teletype open.
* establishes a process group for distribution
* of quits and interrupts from the tty.
*/
ttopen(tp) ttopen(tp)
register struct tty *tp; register struct tty *tp;
{ {
register struct proc *pp; register struct proc *pp;
pp = u.u_procp; pp = u.u_procp;
if (tp->t_state & XCLUSE) { if (tp->t_state&XCLUSE) {
u.u_error = EACCES; u.u_error = EACCES;
return; return;
} }
if ((pp->p_pid == pp->p_pgrp) && !(u.u_ttyp) && !(tp->t_pgrp)){ if ((pp->p_pid == pp->p_pgrp)
&&(u.u_ttyp == NULL)
&&(tp->t_pgrp == 0)) {
u.u_ttyp = tp; u.u_ttyp = tp;
tp->t_pgrp = pp->p_pgrp; tp->t_pgrp = pp->p_pgrp;
} }
tp->t_state &=~WOPEN; tp->t_state &= ~WOPEN;
tp->t_state |= ISOPEN; tp->t_state |= ISOPEN;
} }
ttclose(tp) ttclose(tp)
register struct tty *tp; register struct tty *tp;
{ {
dvi(); dvi();
(*tp->t_proc)(tp, T_RESUME); (*tp->t_proc)(tp, T_RESUME);
evi(); evi();
ttyflush(tp, T_TIME); ttyflush(tp, FREAD);
ttywait(tp); ttywait(tp);
tp->t_state & = ~(WOPEN | ISOPEN); tp->t_state &= ~(ISOPEN|WOPEN);
} }
/*
#define CDEF (CLOCAL | PARODD | PARENB | CREAD | CSTOPB) * common ioctl tty code
#define CDEF1 (CLOCAL | PARENB | CREAD | CSTOPB) */
ttiocmd(tp, cmd, arg, mode)
ttiocom(tp, com, addr, flag)
register struct tty *tp; register struct tty *tp;
caddr_t addr; caddr_t arg;
int com; int cmd;
{ {
register ushort cflg; register ushort cflg;
register int tmod; register int tmod;
register int ldmode; register flag;
ushort iflg; ushort iflg;
struct termio t; struct termio cb;
struct sgttyb told; struct sgttyb tb;
struct tchars toc; struct tchars toc;
switch (com){ switch(cmd) {
case IOCTYPE: case IOCTYPE:
u.u_r.r_val1 = TIOC; u.u_r.r_val1 = TIOC;
break; break;
case TCSETAW: case TCSETAW:
case TCSETAF: case TCSETAF:
ttywait(tp); ttywait(tp);
if (com == TCSETAF) if (cmd == TCSETAF)
ttyflush(tp, T_RESUME); ttyflush(tp, (FREAD|FWRITE));
case TCSETA: case TCSETA:
if (copyin( addr, (caddr_t)&t, sizeof(t))==0){ if (copyin( arg, (caddr_t)&cb, sizeof(cb))==0) {
if (tp->t_line != t.c_line){ if (tp->t_line != cb.c_line) {
if ((t.c_line < 0) || (t.c_line >= linecnt)){ if ((cb.c_line < 0) || (cb.c_line >= linecnt)) {
u.u_error = EINVAL; u.u_error = EINVAL;
break; break;
} }
(*linesw[tp->t_line].l_ioctl)(tp, LDCLOSE, (caddr_t) 0, flag); (*linesw[tp->t_line].l_ioctl)(tp, LDCLOSE, (caddr_t) 0, mode);
} }
ldmode = tp->t_lflag; flag = tp->t_lflag;
tmod = 0; tmod = 0;
if ((tp->t_cflag & CBAUD) != (t.c_cflag & CBAUD)) if ((tp->t_cflag&CBAUD) != (cb.c_cflag&CBAUD))
tmod++; tmod++;
if ((tp->t_cflag & CSIZE) != (t.c_cflag & CSIZE)) if ((tp->t_cflag&CSIZE) != (cb.c_cflag&CSIZE))
tmod++; tmod++;
if ((tp->t_cflag ^ t.c_cflag ) & CDEF) if ((tp->t_cflag ^ cb.c_cflag )&CDEF)
tmod++; tmod++;
if ((tp->t_iflag ^ t.c_iflag ) & IGNBRK) if ((tp->t_iflag ^ cb.c_iflag )&IGNBRK)
tmod++; tmod++;
tp->t_iflag = t.c_iflag; tp->t_iflag = cb.c_iflag;
tp->t_oflag = t.c_oflag; tp->t_oflag = cb.c_oflag;
tp->t_cflag = t.c_cflag; tp->t_cflag = cb.c_cflag;
tp->t_lflag = t.c_lflag; tp->t_lflag = cb.c_lflag;
bcopy(t.c_tcc, tp->t_cc, sizeof(tp->t_cc)); bcopy(cb.c_tcc, tp->t_cc, sizeof(tp->t_cc));
if (tp->t_line != t.c_line) { if (tp->t_line != cb.c_line) {
tp->t_line = t.c_line; tp->t_line = cb.c_line;
(*linesw[tp->t_line].l_ioctl)(tp, LDIOC, (caddr_t) 0, flag); (*linesw[tp->t_line].l_ioctl)(tp, LDOPEN, (caddr_t) 0, mode);
} else if (tp->t_lflag != flag) {
(*linesw[tp->t_line].l_ioctl)(tp, LDCHG, (long) flag, mode);
} }
else if (tmod)
if (tp->t_lflag != ldmode) return(1);
(*linesw[tp->t_line].l_ioctl)(tp, LDCHG, (long) ldmode, flag);
if (tmod) return(1);
} else } else
u.u_error = EFAULT; u.u_error = EFAULT;
break; break;
case TCGETA: case TCGETA:
t.c_iflag = tp->t_iflag; cb.c_iflag = tp->t_iflag;
t.c_oflag = tp->t_oflag; cb.c_oflag = tp->t_oflag;
t.c_cflag = tp->t_cflag; cb.c_cflag = tp->t_cflag;
t.c_lflag = tp->t_lflag; cb.c_lflag = tp->t_lflag;
t.c_line = tp->t_line; cb.c_line = tp->t_line;
bcopy (tp->t_cc, t.c_tcc, sizeof(tp->t_cc)); bcopy (tp->t_cc, cb.c_tcc,NCC);
if (copyout((caddr_t) &t, addr, sizeof(t))) if (copyout((caddr_t)&cb, arg, sizeof(cb)))
u.u_error = EFAULT; u.u_error = EFAULT;
break; break;
case TCXONC: case TCXONC:
switch (addr){ switch (arg) {
case 000: case 0:
(*tp->t_proc)(tp, T_SUSPEND); (*tp->t_proc)(tp, T_SUSPEND);
break; break;
case 001: case 1:
(*tp->t_proc)(tp, T_RESUME); (*tp->t_proc)(tp, T_RESUME);
break; break;
case 002: case 2:
(*tp->t_proc)(tp, T_BLOCK); (*tp->t_proc)(tp, T_BLOCK);
break; break;
case 003: case 3:
(*tp->t_proc)(tp, T_UNBLOCK); (*tp->t_proc)(tp, T_UNBLOCK);
break; break;
default: default:
@ -192,19 +221,21 @@ int com;
break; break;
case TCSBRK: case TCSBRK:
ttywait(tp); ttywait(tp);
if(addr == 0) if(arg == 0)
(*tp->t_proc)(tp, T_BREAK); (*tp->t_proc)(tp, T_BREAK);
break; break;
case TIOCFLUSH: case TIOCFLUSH:
ttyflush(tp, T_RESUME); ttyflush(tp, (FREAD|FWRITE));
break; break;
case TCFLSH: case TCFLSH:
switch (addr){ switch (arg) {
case 000: case 0:
case 001: case 1:
case 002: case 2:
ttyflush(tp, addr); ttyflush(tp, arg);
break; break;
default: default:
u.u_error = EINVAL; u.u_error = EINVAL;
} }
@ -214,52 +245,52 @@ int com;
break; break;
case TIOCSETP: case TIOCSETP:
ttywait(tp); ttywait(tp);
ttyflush(tp, T_RESUME); ttyflush(tp, (FREAD|FWRITE));
case TIOCSETN: case TIOCSETN:
if (copyin( addr, (caddr_t) &told, sizeof(told))){ if (copyin( arg, (caddr_t)&tb, sizeof(tb))) {
cflg = tp->t_cflag; cflg = tp->t_cflag;
iflg = tp->t_iflag; iflg = tp->t_iflag;
tp->t_iflag = 0; tp->t_iflag = 0;
tp->t_oflag = 0; tp->t_oflag = 0;
tp->t_lflag = 0; tp->t_lflag = 0;
tp->t_cflag = (told.sg_ispeed & 0xf) | CREAD; tp->t_cflag = (tb.sg_ispeed&CBAUD)|CREAD;
tp->t_cflag |= CLOCAL | CSTOPB; tp->t_cflag |= CLOCAL|CSTOPB;
tp->t_cc[VERASE] = told.sg_erase; tp->t_cc[VERASE] = tb.sg_erase;
tp->t_cc[VKILL] = told.sg_kill; tp->t_cc[VKILL] = tb.sg_kill;
ldmode = told.sg_flags; flag = tb.sg_flags;
if (ldmode & O_TBDELAY){ if (flag&O_TBDELAY) {
if (ldmode & O_TAB1) if (flag&O_TAB1)
tp->t_oflag |= TAB1; tp->t_oflag |= TAB1;
if (ldmode & O_TAB2) if (flag&O_TAB2)
tp->t_oflag |= TAB2; tp->t_oflag |= TAB2;
} }
if (ldmode & O_LCASE){ if (flag&O_LCASE) {
tp->t_iflag |= IUCLC; tp->t_iflag |= IUCLC;
tp->t_oflag |= OLCUC; tp->t_oflag |= OLCUC;
tp->t_lflag |= XCASE; tp->t_lflag |= XCASE;
} }
if (ldmode & O_ECHO) if (flag&O_ECHO)
tp->t_lflag |= ECHO; tp->t_lflag |= ECHO;
if (ldmode & O_CRMOD){ if (flag&O_CRMOD) {
tp->t_iflag |= ICRNL; tp->t_iflag |= ICRNL;
tp->t_oflag |= ONLCR; tp->t_oflag |= ONLCR;
} }
if (ldmode & O_CR1) if (flag&O_CR1)
tp->t_oflag |= CR1; tp->t_oflag |= CR1;
if (ldmode & O_CR2) if (flag&O_CR2)
tp->t_oflag |= CR2; tp->t_oflag |= CR2;
if (ldmode & O_NL1) if (flag&O_NL1)
tp->t_oflag |= NLDLY; tp->t_oflag |= NLDLY;
if (ldmode & O_NL2) if (flag&O_NL2)
tp->t_oflag |= NLDLY; tp->t_oflag |= NLDLY;
if (ldmode & O_RAW){ if (flag&O_RAW) {
tp->t_cc[VTIME] = 6; tp->t_cc[VTIME] = 6;
tp->t_cc[VMIN] = 1; tp->t_cc[VMIN] = 1;
tp->t_iflag &= ~(ICRNL | IUCLC); tp->t_iflag &= ~(ICRNL|IUCLC);
tp->t_cflag |= CS8; tp->t_cflag |= CS8;
} }
else else
if (ldmode & O_CBREAK){ if (flag&O_CBREAK) {
tp->t_cc[VTIME] = 6; tp->t_cc[VTIME] = 6;
tp->t_cc[VMIN] = 1; tp->t_cc[VMIN] = 1;
tp->t_iflag |= IXON | ISTRIP | IGNBRK; tp->t_iflag |= IXON | ISTRIP | IGNBRK;
@ -277,29 +308,29 @@ int com;
} }
tp->t_iflag |= INPCK; tp->t_iflag |= INPCK;
tp->t_cflag |= PARENB; tp->t_cflag |= PARENB;
if (ldmode & O_ODDP) if (flag&O_ODDP)
if (ldmode &O_EVENP){ if (flag&O_EVENP) {
tp->t_iflag &= ~INPCK; tp->t_iflag &= ~INPCK;
tp->t_cflag &= ~PARENB; tp->t_cflag &= ~PARENB;
} }
else else
tp->t_cflag |= PARODD; tp->t_cflag |= PARODD;
if (ldmode &O_VTDELAY) if (flag&O_VTDELAY)
tp->t_oflag |= FF1; tp->t_oflag |= FF1;
if (ldmode & O_BSDELAY) if (flag&O_BSDELAY)
tp->t_oflag |= BS1; tp->t_oflag |= BS1;
if (ldmode & O_TANDEM) if (flag&O_TANDEM)
tp->t_iflag |= IXOFF; tp->t_iflag |= IXOFF;
if (iflg & ISPCI) if (iflg&ISPCI)
tp->t_iflag |= ISPCI; tp->t_iflag |= ISPCI;
tmod = 0; tmod = 0;
if ((tp->t_cflag & CBAUD) != (cflg & CBAUD)) if ((tp->t_cflag&CBAUD) != (cflg&CBAUD))
tmod++; tmod++;
if ((tp->t_cflag & CSIZE) != (cflg & CSIZE)) if ((tp->t_cflag&CSIZE) != (cflg&CSIZE))
tmod++; tmod++;
if ((tp->t_cflag ^ cflg) & CDEF1) if ((tp->t_cflag ^ cflg)&CDEF1)
tmod++; tmod++;
if ((tp->t_iflag ^ iflg) & IGNBRK) if ((tp->t_iflag ^ iflg)&IGNBRK)
tmod++; tmod++;
if (tmod) if (tmod)
return(1); return(1);
@ -308,48 +339,48 @@ int com;
u.u_error = EFAULT; u.u_error = EFAULT;
break; break;
case TIOCGETP: case TIOCGETP:
told.sg_ospeed = told.sg_ispeed = tp->t_cflag & CBAUD; tb.sg_ospeed = tb.sg_ispeed = tp->t_cflag&CBAUD;
told.sg_erase = tp->t_cc[VERASE]; tb.sg_erase = tp->t_cc[VERASE];
told.sg_kill = (long)tp->t_cc[VKILL]; tb.sg_kill = (long)tp->t_cc[VKILL];
ldmode = 0; flag = 0;
if ((tp->t_lflag & ICANON) || (tp->t_lflag & ISIG) ) if ((tp->t_lflag&ICANON) || (tp->t_lflag&ISIG) )
ldmode |= O_RAW; flag |= O_RAW;
if ((tp->t_lflag & ICANON) || (tp->t_lflag & ISIG)) if ((tp->t_lflag&ICANON) || (tp->t_lflag&ISIG))
ldmode |= O_CBREAK; flag |= O_CBREAK;
if (tp->t_lflag & XCASE) if (tp->t_lflag&XCASE)
ldmode |= O_LCASE; flag |= O_LCASE;
if (tp->t_lflag & ECHO) if (tp->t_lflag&ECHO)
ldmode |= O_ECHO; flag |= O_ECHO;
if (tp->t_cflag & PARODD) if (tp->t_cflag&PARODD)
ldmode |= O_ODDP; flag |= O_ODDP;
else else
if (tp->t_iflag & INPCK) if (tp->t_iflag&INPCK)
ldmode |= O_EVENP; flag |= O_EVENP;
else else
ldmode |= O_EVENP | O_ODDP; flag |= O_EVENP | O_ODDP;
if (tp->t_oflag & ONLCR){ if (tp->t_oflag&ONLCR) {
ldmode |= O_CRMOD; flag |= O_CRMOD;
if (tp->t_oflag & CR1) if (tp->t_oflag&CR1)
ldmode |= O_CR1; flag |= O_CR1;
if (tp->t_oflag & CR2) if (tp->t_oflag&CR2)
ldmode |= O_CR2; flag |= O_CR2;
} }
else { else {
if (tp->t_oflag & CR1) if (tp->t_oflag&CR1)
ldmode |= O_NL1; flag |= O_NL1;
if (tp->t_oflag & CR2) if (tp->t_oflag&CR2)
ldmode |= O_NL2; flag |= O_NL2;
} }
if (((tp->t_oflag &TABDLY) == TAB3) || (tp->t_oflag & TAB1)) if (((tp->t_oflag&TABDLY) == TAB3) || (tp->t_oflag&TAB1))
ldmode |= O_TBDELAY; flag |= O_TBDELAY;
if (tp->t_oflag & FF1) if (tp->t_oflag&FF1)
ldmode |= O_VTDELAY; flag |= O_VTDELAY;
if (tp->t_oflag & BSDLY) if (tp->t_oflag&BSDLY)
ldmode |= O_BSDELAY; flag |= O_BSDELAY;
if (tp->t_iflag & IXOFF) if (tp->t_iflag&IXOFF)
ldmode |= O_TANDEM; flag |= O_TANDEM;
told.sg_flags = ldmode; tb.sg_flags = flag;
if (copyout((caddr_t) &told, addr, sizeof(told))) if (copyout((caddr_t)&tb, arg, sizeof(tb)))
u.u_error = EFAULT; u.u_error = EFAULT;
break; break;
case TCXCLUSE: case TCXCLUSE:
@ -359,10 +390,10 @@ int com;
tp->t_state &= ~XCLUSE; tp->t_state &= ~XCLUSE;
break; break;
case TIOCSETC: case TIOCSETC:
if (copyin( addr, (caddr_t) &toc, sizeof(toc))){ if (copyin( arg, (caddr_t)&toc, sizeof(toc))) {
tp->t_cc[VINTR] = toc.t_intrc; tp->t_cc[VINTR] = toc.t_intrc;
tp->t_cc[VQUIT] = toc.t_quitc; tp->t_cc[VQUIT] = toc.t_quitc;
if (tp->t_lflag & ICANON) if (tp->t_lflag&ICANON)
tp->t_cc[VEOF] = toc.t_eofc; tp->t_cc[VEOF] = toc.t_eofc;
} }
else else
@ -375,12 +406,12 @@ int com;
toc.t_startc = CSTART; toc.t_startc = CSTART;
toc.t_stopc = CSTOP; toc.t_stopc = CSTOP;
toc.t_brkc = 0; toc.t_brkc = 0;
if (copyout((caddr_t)&toc, addr, sizeof(toc))) if (copyout((caddr_t)&toc, arg, sizeof(toc)))
u.u_error =EFAULT; u.u_error =EFAULT;
break; break;
default: default:
if ((com & IOCTYPE) == LDIOC) if ((cmd&IOCTYPE) == LDIOC)
(*linesw[tp->t_line].l_ioctl)(tp, com, addr, flag); (*linesw[tp->t_line].l_ioctl)(tp, cmd, arg, mode);
else else
u.u_error = EINVAL; u.u_error = EINVAL;
} }
@ -404,48 +435,55 @@ register struct tty *tp;
{ {
dvi(); dvi();
while ((tp->t_outq.c_cc) || (tp->t_state & (BUSY | TIMEOUT))){ while (tp->t_outq.c_cc || (tp->t_state&(BUSY|TIMEOUT))) {
tp->t_state |= TTIOW; tp->t_state |= TTIOW;
sleep( &tp->t_oflag, TTOPRI); sleep(&tp->t_oflag, TTOPRI);
} }
evi(); evi();
} }
ttyflush(tp, com) /*
* flush TTY queues
*/
ttyflush(tp, cmd)
register struct tty *tp; register struct tty *tp;
{ {
register struct cblock *p; register struct cblock *cp;
register unsigned s; register s;
if (com & T_SUSPEND){ if (cmd&FWRITE) {
while (p = getcb ( &tp->t_outq)) while ((cp = getcb(&tp->t_outq)) != NULL)
putcf(p); putcf(cp);
(*tp->t_proc)(tp, T_WFLUSH); (*tp->t_proc)(tp, T_WFLUSH);
if (tp->t_state & OASLP){ if (tp->t_state&OASLP) {
tp->t_state &= ~OASLP; tp->t_state &= ~OASLP;
wakeup(&tp->t_outq); wakeup(&tp->t_outq);
} }
if (tp->t_state & TTIOW){ if (tp->t_state&TTIOW) {
tp->t_state &= ~TTIOW; tp->t_state &= ~TTIOW;
wakeup(&tp->t_oflag); wakeup(&tp->t_oflag);
} }
} }
if (com & T_TIME){ if (cmd&FREAD) {
while (p = (getcb(&tp->t_canq))) while ((cp = getcb(&tp->t_canq)) != NULL)
putcf(p); putcf(cp);
s = dvi(); s = dvi();
while (p = (getcb(&tp->t_rawq))) while ((cp = getcb(&tp->t_rawq)) != NULL)
putcf(p); putcf(cp);
tp->t_delct = 0; tp->t_delct = 0;
rvi(s); rvi(s);
(*tp->t_proc)(tp, T_RFLUSH); (*tp->t_proc)(tp, T_RFLUSH);
if (tp->t_state & IASLP){ if (tp->t_state&IASLP) {
tp->t_state &= ~IASLP; tp->t_state &= ~IASLP;
wakeup(&tp->t_rawq); wakeup(&tp->t_rawq);
} }
} }
} }
/*
* Transfer raw input list to canonical list,
* doing erase-kill processing and handling escapes.
*/
canon(tp) canon(tp)
register struct tty *tp; register struct tty *tp;
{ {
@ -457,22 +495,22 @@ register struct tty *tp;
dvi(tp); dvi(tp);
if ((tp->t_rawq.c_cc) == 0) if ((tp->t_rawq.c_cc) == 0)
tp->t_delct = 0; tp->t_delct = 0;
while (tp->t_delct == 0){ while (tp->t_delct == 0) {
if ((tp->t_state & CARR_ON) == 0){ if ((tp->t_state&CARR_ON) == 0) {
evi(); evi();
return; return;
} }
if (!(tp->t_lflag & ICANON) && !(tp->t_cc[VEOF])){ if (!(tp->t_lflag&ICANON)&&!(tp->t_cc[VEOF])) {
if (tp->t_cc[VEOL] == 0) if (tp->t_cc[VEOL] == 0)
break; break;
tp->t_state &= ~RTO; tp->t_state &= ~RTO;
if ((tp->t_state & TACT) == 0) if ((tp->t_state&TACT) == 0)
tttimeout(tp); tttimeout(tp);
} }
tp->t_state |= IASLP; tp->t_state |= IASLP;
sleep(tp, TTIPRI); sleep(tp, TTIPRI);
} }
if (!(tp->t_lflag & ICANON)){ if (!(tp->t_lflag&ICANON)) {
tp->t_canq = tp->t_rawq; tp->t_canq = tp->t_rawq;
tp->t_rawq = ttnulq; tp->t_rawq = ttnulq;
tp->t_delct=0; tp->t_delct=0;
@ -482,29 +520,29 @@ register struct tty *tp;
evi(); evi();
cbp = canonb; cbp = canonb;
nc = 0; nc = 0;
if (tp->t_state & IEXTPROC){ if (tp->t_state&IEXTPROC) {
do { do {
if (((c = getc(&tp->t_rawq)) < 0) || (c == tp->t_cc[VEOF])) if (((c = getc(&tp->t_rawq)) < 0) || (c == tp->t_cc[VEOF]))
break; break;
putc(c, &tp->t_canq); putc(c, &tp->t_canq);
sysinfo.canch++; sysinfo.canch++;
} }
while ((c != '\n') && (c != tp->t_cc[VEOL])); while ((c != '\n')&&(c != tp->t_cc[VEOL]));
mret: mret:
tp->t_delct--; tp->t_delct--;
return; return;
} }
while ((c = getc(&tp->t_rawq)) >= 0){ while ((c = getc(&tp->t_rawq)) >= 0) {
if (nc == 0) if (nc == 0)
if (c == '\\') if (c == '\\')
nc++; nc++;
else { else {
if (c == tp->t_cc[VERASE]){ if (c == tp->t_cc[VERASE]) {
if (cbp > canonb) if (cbp > canonb)
cbp--; cbp--;
continue; continue;
} }
if (c == tp->t_cc[VKILL]){ if (c == tp->t_cc[VKILL]) {
cbp = canonb; cbp = canonb;
continue; continue;
} }
@ -520,8 +558,8 @@ mret:
(c == tp->t_cc[VEOF])) (c == tp->t_cc[VEOF]))
cbp--; cbp--;
else else
if (tp->t_lflag & XCASE){ if (tp->t_lflag&XCASE) {
if ((c < 0x80) && (maptab[c])){ if ((c < 0x80)&&(maptab[c])) {
cbp--; cbp--;
c = maptab[c]; c = maptab[c];
} }
@ -536,7 +574,7 @@ mret:
*cbp++ = c; *cbp++ = c;
if ((c == '\n') || (c == tp->t_cc[VEOL])) if ((c == '\n') || (c == tp->t_cc[VEOL]))
break; break;
if (cbp >= &canonb[Canbsiz]) if (cbp >=&canonb[Canbsiz])
cbp--; cbp--;
} }
c = cbp - canonb; c = cbp - canonb;
@ -547,6 +585,11 @@ mret:
goto mret; goto mret;
} }
/*
* Restart typewriter output following a delay timeout.
* The name of the routine is passed to the timeout
* subroutine and it is called during a clock interrupt.
*/
ttrstrt(tp) ttrstrt(tp)
register struct tty *tp; register struct tty *tp;
{ {
@ -554,6 +597,10 @@ register struct tty *tp;
(*tp->t_proc)(tp, T_TIME); (*tp->t_proc)(tp, T_TIME);
} }
/*
* Called from device's read routine after it has
* calculated the tty-structure given as argument.
*/
ttread(tp) ttread(tp)
register struct tty *tp; register struct tty *tp;
{ {
@ -568,13 +615,13 @@ register struct tty *tp;
ur; ur;
tc = &tp->t_canq; tc = &tp->t_canq;
if (tc->c_cc == 0){ if (tc->c_cc == 0) {
if (u.u_fmode & FPIPE) if (u.u_fmode&FPIPE)
return; return;
canon(tp); canon(tp);
} }
while ((u.u_count) && (u.u_error == 0)){ while ((u.u_count)&&(u.u_error == 0)) {
if (u.u_count >= CLSIZE){ if (u.u_count >= CLSIZE) {
if ((ur.cf = getcb(tc)) == 0) if ((ur.cf = getcb(tc)) == 0)
break; break;
count = min(u.u_count, ur.cf->c_last - ur.cf->c_first); count = min(u.u_count, ur.cf->c_last - ur.cf->c_first);
@ -584,7 +631,7 @@ register struct tty *tp;
} }
else { else {
count = 0; count = 0;
while (count < u.u_count){ while (count < u.u_count) {
if ((c = getc(tc)) < 0) if ((c = getc(tc)) < 0)
break; break;
ur.rc[count] = c; ur.rc[count] = c;
@ -598,30 +645,34 @@ register struct tty *tp;
u.u_base.half.right += count; u.u_base.half.right += count;
u.u_count -= count; u.u_count -= count;
} }
if ((tp->t_state & TBLOCK) && (tp->t_rawq.c_cc < TTXOLO)) if ((tp->t_state&TBLOCK)&&(tp->t_rawq.c_cc < TTXOLO))
(*tp->t_proc)(tp, T_UNBLOCK); (*tp->t_proc)(tp, T_UNBLOCK);
} }
/*
* Called from device's write routine after it has
* calculated the tty-structure given as argument.
*/
ttwrite(tp) ttwrite(tp)
register struct tty *tp; register struct tty *tp;
{ {
register count; register count;
register struct cblock *cf; register struct cblock *cf;
if (tp->t_state & CARR_ON){ if (tp->t_state&CARR_ON) {
while (u.u_count){ while (u.u_count) {
dvi(); dvi();
while (tp->t_outq.c_cc > tthiwat[tp->t_cflag & CBAUD]) { while (tp->t_outq.c_cc > tthiwat[tp->t_cflag&CBAUD]) {
(*tp->t_proc)(tp, T_OUTPUT); (*tp->t_proc)(tp, T_OUTPUT);
tp->t_state |= OASLP; tp->t_state |= OASLP;
sleep(&tp->t_outq, TTOPRI); sleep(&tp->t_outq, TTOPRI);
} }
evi(); evi();
if (u.u_count >= 8){ if (u.u_count >= 8) {
if ((cf = getcf()) == 0) if ((cf = getcf()) == 0)
break; break;
count = min(u.u_count, cf->c_last); count = min(u.u_count, cf->c_last);
if (copyin(u.u_base, cf->c_data, count)){ if (copyin(u.u_base, cf->c_data, count)) {
u.u_error = EFAULT; u.u_error = EFAULT;
putcf(cf); putcf(cf);
break; break;
@ -633,7 +684,7 @@ register struct tty *tp;
} }
else { else {
char wc; char wc;
if (fubyte(u.u_base.l++, &wc)){ if (fubyte(u.u_base.l++, &wc)) {
u.u_error = EFAULT; u.u_error = EFAULT;
break; break;
} }
@ -649,7 +700,7 @@ register struct tty *tp;
ttchkopen() ttchkopen()
{ {
if (noterm < numterm){ if (noterm < numterm) {
noterm++; noterm++;
return(0); return(0);
} }