projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
early non-blocking stuff
[unix-history]
/
usr
/
src
/
sys
/
kern
/
tty.c
diff --git
a/usr/src/sys/kern/tty.c
b/usr/src/sys/kern/tty.c
index
d33a8e5
..
901e6c5
100644
(file)
--- a/
usr/src/sys/kern/tty.c
+++ b/
usr/src/sys/kern/tty.c
@@
-1,4
+1,4
@@
-/* tty.c
3.17 %G%
*/
+/* tty.c
4.15 82/01/14
*/
/*
* TTY subroutines common to more than one line discipline
/*
* TTY subroutines common to more than one line discipline
@@
-9,7
+9,6
@@
#include "../h/user.h"
#include "../h/tty.h"
#include "../h/proc.h"
#include "../h/user.h"
#include "../h/tty.h"
#include "../h/proc.h"
-#include "../h/mx.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/reg.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/reg.h"
@@
-19,18
+18,6
@@
char partab[];
char partab[];
-/*
- * When running dz's using only SAE (silo alarm) on input
- * it is necessary to call dzrint() at clock interrupt time.
- * This is unsafe unless spl5()s in tty code are changed to
- * spl6()s to block clock interrupts. Note that the dh driver
- * currently in use works the same way as the dz, even though
- * we could try to more intelligently manage its silo.
- * Thus don't take this out if you have no dz's unless you
- * change clock.c and dhtimer().
- */
-#define spl5 spl6
-
/*
* Input mapping table-- if an entry is non-zero, when the
* corresponding character is typed preceded by "\" the escape
/*
* Input mapping table-- if an entry is non-zero, when the
* corresponding character is typed preceded by "\" the escape
@@
-57,6
+44,11
@@
char maptab[] ={
'X','Y','Z',000,000,000,000,000,
};
'X','Y','Z',000,000,000,000,000,
};
+short tthiwat[16] =
+ { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,650,650 };
+short ttlowat[16] =
+ { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
+
#define OBUFSIZ 100
/*
#define OBUFSIZ 100
/*
@@
-81,9
+73,6
@@
register struct tty *tp;
tlun.t_flushc = CTRL(o);
tlun.t_werasc = CTRL(w);
tlun.t_lnextc = CTRL(v);
tlun.t_flushc = CTRL(o);
tlun.t_werasc = CTRL(w);
tlun.t_lnextc = CTRL(v);
- tlun.t_lintr = CTRL(c);
- tlun.t_lerase = CTRL(h);
- tlun.t_lkill = CTRL(u);
tp->t_local = 0;
tp->t_lstate = 0;
/* end local */
tp->t_local = 0;
tp->t_lstate = 0;
/* end local */
@@
-93,13
+82,13
@@
register struct tty *tp;
* Wait for output to drain, then flush input waiting.
*/
wflushtty(tp)
* Wait for output to drain, then flush input waiting.
*/
wflushtty(tp)
-register struct tty *tp;
+
register struct tty *tp;
{
(void) spl5();
{
(void) spl5();
- while (tp->t_outq.c_cc && tp->t_state&CARR_ON) {
+ while (tp->t_outq.c_cc && tp->t_state&
TS_
CARR_ON) {
(*tp->t_oproc)(tp);
(*tp->t_oproc)(tp);
- tp->t_state |= ASLEEP;
+ tp->t_state |=
TS_
ASLEEP;
sleep((caddr_t)&tp->t_outq, TTOPRI);
}
flushtty(tp, FREAD|FWRITE);
sleep((caddr_t)&tp->t_outq, TTOPRI);
}
flushtty(tp, FREAD|FWRITE);
@@
-114,8
+103,6
@@
register struct tty *tp;
{
register s;
{
register s;
- if (tp->t_line == NETLDISC)
- return;
s = spl6();
if (rw & FREAD) {
while (getc(&tp->t_canq) >= 0)
s = spl6();
if (rw & FREAD) {
while (getc(&tp->t_canq) >= 0)
@@
-124,7
+111,7
@@
register struct tty *tp;
}
if (rw & FWRITE) {
wakeup((caddr_t)&tp->t_outq);
}
if (rw & FWRITE) {
wakeup((caddr_t)&tp->t_outq);
- tp->t_state &= ~TTSTOP;
+ tp->t_state &= ~T
S_T
TSTOP;
(*cdevsw[major(tp->t_dev)].d_stop)(tp);
while (getc(&tp->t_outq) >= 0)
;
(*cdevsw[major(tp->t_dev)].d_stop)(tp);
while (getc(&tp->t_outq) >= 0)
;
@@
-150,11
+137,11
@@
register struct tty *tp;
x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
if (tp->t_rawq.c_cc > TTYHOG) {
flushtty(tp, FREAD|FWRITE);
x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
if (tp->t_rawq.c_cc > TTYHOG) {
flushtty(tp, FREAD|FWRITE);
- tp->t_state &= ~TBLOCK;
+ tp->t_state &= ~T
S_T
BLOCK;
}
if (x >= TTYHOG/2) {
if (putc(tun.t_stopc, &tp->t_outq)==0) {
}
if (x >= TTYHOG/2) {
if (putc(tun.t_stopc, &tp->t_outq)==0) {
- tp->t_state |= TBLOCK;
+ tp->t_state |= T
S_T
BLOCK;
tp->t_char++;
ttstart(tp);
}
tp->t_char++;
ttstart(tp);
}
@@
-171,7
+158,11
@@
ttrstrt(tp)
register struct tty *tp;
{
register struct tty *tp;
{
- tp->t_state &= ~TIMEOUT;
+ if (tp == 0) {
+ printf("ttrstrt: arg was 0!\n");
+ return;
+ }
+ tp->t_state &= ~TS_TIMEOUT;
ttstart(tp);
}
ttstart(tp);
}
@@
-187,7
+178,7
@@
register struct tty *tp;
register s;
s = spl5();
register s;
s = spl5();
- if((tp->t_state&(T
IMEOUT|TTSTOP|
BUSY)) == 0)
+ if((tp->t_state&(T
S_TIMEOUT|TS_TTSTOP|TS_
BUSY)) == 0)
(*tp->t_oproc)(tp);
splx(s);
}
(*tp->t_oproc)(tp);
splx(s);
}
@@
-195,10
+186,12
@@
register struct tty *tp;
/*
* Common code for tty ioctls.
*/
/*
* Common code for tty ioctls.
*/
-ttioctl(com, tp, addr, dev, flag)
+/*ARGSUSED*/
+ttioctl(tp, com, addr, flag)
register struct tty *tp;
caddr_t addr;
{
register struct tty *tp;
caddr_t addr;
{
+ int dev;
unsigned t;
struct sgttyb iocb;
struct clist tq;
unsigned t;
struct sgttyb iocb;
struct clist tq;
@@
-206,6
+199,16
@@
caddr_t addr;
register c;
int temp;
register c;
int temp;
+ /*
+ * This is especially so that isatty() will
+ * fail when carrier is gone.
+ */
+ if ((tp->t_state&TS_CARR_ON) == 0) {
+ u.u_error = EBADF;
+ return (1);
+ }
+
+ dev = tp->t_dev;
/*
* If the ioctl involves modification,
* insist on being able to write the device,
/*
* If the ioctl involves modification,
* insist on being able to write the device,
@@
-213,7
+216,9
@@
caddr_t addr;
*/
switch(com) {
*/
switch(com) {
- case TIOCHPCL:
+ case TIOCSETD:
+ case TIOCSETP:
+ case TIOCSETN:
case TIOCFLUSH:
case TIOCSETC:
case TIOCSLTC:
case TIOCFLUSH:
case TIOCSETC:
case TIOCSLTC:
@@
-222,10
+227,12
@@
caddr_t addr;
case TIOCLBIC:
case TIOCLSET:
case TIOCSTI:
case TIOCLBIC:
case TIOCLSET:
case TIOCSTI:
+/* this is reasonable, but impractical...
if ((flag & FWRITE) == 0) {
u.u_error = EBADF;
return (1);
}
if ((flag & FWRITE) == 0) {
u.u_error = EBADF;
return (1);
}
+ */
while (tp->t_line == NTTYDISC &&
u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
(u.u_procp->p_flag&SVFORK) == 0 &&
while (tp->t_line == NTTYDISC &&
u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
(u.u_procp->p_flag&SVFORK) == 0 &&
@@
-274,17
+281,6
@@
caddr_t addr;
(void) spl0();
break;
(void) spl0();
break;
- /*
- * Prevent more opens on channel
- */
- case TIOCEXCL:
- tp->t_state |= XCLUDE;
- break;
-
- case TIOCNXCL:
- tp->t_state &= ~XCLUDE;
- break;
-
/*
* Set new parameters
*/
/*
* Set new parameters
*/
@@
-295,39
+291,29
@@
caddr_t addr;
return(1);
}
(void) spl5();
return(1);
}
(void) spl5();
- if (tp->t_line == 0) {
- if (com == TIOCSETP)
- wflushtty(tp);
- while (canon(tp)>=0)
- ;
- } else if (tp->t_line == NTTYDISC) {
- if (tp->t_flags&RAW || iocb.sg_flags&RAW ||
- com == TIOCSETP)
- wflushtty(tp);
- else if ((tp->t_flags&CBREAK) != (iocb.sg_flags&CBREAK)) {
- if (iocb.sg_flags & CBREAK) {
- catq(&tp->t_rawq, &tp->t_canq);
- tq = tp->t_rawq;
- tp->t_rawq = tp->t_canq;
- tp->t_canq = tq;
- } else {
- tp->t_local |= LPENDIN;
- if (tp->t_canq.c_cc)
- panic("ioccom canq");
- if (tp->t_chan)
- (void) sdata(tp->t_chan);
- else
- wakeup((caddr_t)&tp->t_rawq);
- }
+ if (tp->t_flags&RAW || iocb.sg_flags&RAW ||
+ com == TIOCSETP)
+ wflushtty(tp);
+ else if ((tp->t_flags&CBREAK) != (iocb.sg_flags&CBREAK)) {
+ if (iocb.sg_flags & CBREAK) {
+ catq(&tp->t_rawq, &tp->t_canq);
+ tq = tp->t_rawq;
+ tp->t_rawq = tp->t_canq;
+ tp->t_canq = tq;
+ } else {
+ tp->t_local |= LPENDIN;
+ ttwakeup(tp);
}
}
}
}
- if ((tp->t_state&SPEEDS)==0) {
- tp->t_ispeed = iocb.sg_ispeed;
- tp->t_ospeed = iocb.sg_ospeed;
- }
+ tp->t_ispeed = iocb.sg_ispeed;
+ tp->t_ospeed = iocb.sg_ospeed;
tp->t_erase = iocb.sg_erase;
tp->t_kill = iocb.sg_kill;
tp->t_flags = iocb.sg_flags;
tp->t_erase = iocb.sg_erase;
tp->t_kill = iocb.sg_kill;
tp->t_flags = iocb.sg_flags;
+ if (tp->t_flags & RAW) {
+ tp->t_state &= ~TS_TTSTOP;
+ ttstart(tp);
+ }
(void) spl0();
break;
(void) spl0();
break;
@@
-348,21
+334,33
@@
caddr_t addr;
* Hang up line on last close
*/
case TIOCHPCL:
* Hang up line on last close
*/
case TIOCHPCL:
- tp->t_state |= HUPCLS;
+ tp->t_state |=
TS_
HUPCLS;
break;
break;
- case TIOCFLUSH:
- flushtty(tp, FREAD|FWRITE);
+ case TIOCFLUSH: {
+ int flags;
+ if (addr == 0)
+ flags = FREAD|FWRITE;
+ else if (copyin(addr, (caddr_t)&flags, sizeof (flags))) {
+ u.u_error = EFAULT;
+ return(1);
+ }
+ flushtty(tp, flags);
break;
break;
+ }
- /*
- * Ioctl entries to line discipline
- */
- case DIOCSETP:
- case DIOCGETP:
- if ((*linesw[tp->t_line].l_ioctl)(com, tp, addr))
- u.u_error = ENOTTY;
+ case FIONBIO: {
+ int nbio;
+ if (copyin(addr, (caddr_t)&nbio, sizeof (nbio))) {
+ u.u_error = EFAULT;
+ return(1);
+ }
+ if (nbio)
+ tp->t_state |= TS_NBIO;
+ else
+ tp->t_state &= ~TS_NBIO;
break;
break;
+ }
/*
* Set and fetch special characters
/*
* Set and fetch special characters
@@
-395,28
+393,7
@@
caddr_t addr;
* Return number of characters immediately available.
*/
case FIONREAD: {
* Return number of characters immediately available.
*/
case FIONREAD: {
- off_t nread;
-
- switch (tp->t_line) {
-
- case NETLDISC:
- nread = tp->t_rec ? tp->t_inbuf : 0;
- break;
-
- case 0:
- (void) spl5();
- while (canon(tp)>=0)
- ;
- (void) spl0();
- /* fall into ... */
-
- case NTTYDISC:
- nread = tp->t_canq.c_cc;
- if (tp->t_flags & (RAW|CBREAK))
- nread += tp->t_rawq.c_cc;
- break;
-
- }
+ off_t nread = ttnread(tp);
if (copyout((caddr_t)&nread, addr, sizeof (off_t)))
u.u_error = EFAULT;
break;
if (copyout((caddr_t)&nread, addr, sizeof (off_t)))
u.u_error = EFAULT;
break;
@@
-490,3
+467,53
@@
caddr_t addr;
}
return(1);
}
}
return(1);
}
+
+ttnread(tp)
+ struct tty *tp;
+{
+ int nread = 0;
+
+ if (tp->t_local & LPENDIN)
+ ttypend(tp);
+ nread = tp->t_canq.c_cc;
+ if (tp->t_flags & (RAW|CBREAK))
+ nread += tp->t_rawq.c_cc;
+ return (nread);
+}
+
+ttselect(dev, rw)
+ dev_t dev;
+ int rw;
+{
+ register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
+ int nread;
+ int s = spl5();
+
+ switch (rw) {
+
+ case FREAD:
+ nread = ttnread(tp);
+ if (nread > 0)
+ goto win;
+ if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
+ tp->t_state |= TS_RCOLL;
+ else
+ tp->t_rsel = u.u_procp;
+ break;
+
+ case FWRITE:
+ if (tp->t_outq.c_cc <= TTLOWAT(tp))
+ goto win;
+printf("wsel block\n");
+ if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
+ tp->t_state |= TS_WCOLL;
+ else
+ tp->t_wsel = u.u_procp;
+ break;
+ }
+ splx(s);
+ return (0);
+win:
+ splx(s);
+ return (1);
+}