early non-blocking stuff
[unix-history] / usr / src / sys / kern / tty.c
index 2b53375..901e6c5 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty.c   3.20    %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"
 
 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
@@ -95,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);
@@ -116,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)
@@ -126,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 &= ~TS_TTSTOP;
                (*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)
                        ;
@@ -152,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 &= ~TS_TBLOCK;
        }
        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 |= TS_TBLOCK;
                        tp->t_char++;
                        ttstart(tp);
                }
                        tp->t_char++;
                        ttstart(tp);
                }
@@ -173,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);
 }
 
@@ -189,7 +178,7 @@ register struct tty *tp;
        register s;
 
        s = spl5();
        register s;
 
        s = spl5();
-       if((tp->t_state&(TIMEOUT|TTSTOP|BUSY)) == 0)
+       if((tp->t_state&(TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0)
                (*tp->t_oproc)(tp);
        splx(s);
 }
                (*tp->t_oproc)(tp);
        splx(s);
 }
@@ -197,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;
@@ -212,11 +203,12 @@ caddr_t addr;
         * This is especially so that isatty() will
         * fail when carrier is gone.
         */
         * This is especially so that isatty() will
         * fail when carrier is gone.
         */
-       if ((tp->t_state&CARR_ON) == 0) {
+       if ((tp->t_state&TS_CARR_ON) == 0) {
                u.u_error = EBADF;
                return (1);
        }
 
                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,
@@ -289,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
         */
@@ -310,44 +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) 
-                               ;
-#ifdef notdef
-                       wakeup((caddr_t)&tp->t_rawq);
-#endif
-               } 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");
-#ifdef notdef
-                                       if (tp->t_chan)
-                                               (void) sdata(tp->t_chan);
-                                       else
-#endif
-                                               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;
 
@@ -368,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
@@ -415,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;
@@ -510,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);
+}