4.2 distribution
[unix-history] / usr / src / sys / kern / tty_pty.c
index ee7a4fb..3a9986f 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_pty.c       4.22    82/07/21        */
+/*     tty_pty.c       6.1     83/07/29        */
 
 /*
  * Pseudo-teletype Driver
 
 /*
  * Pseudo-teletype Driver
@@ -9,13 +9,15 @@
 #if NPTY > 0
 #include "../h/param.h"
 #include "../h/systm.h"
 #if NPTY > 0
 #include "../h/param.h"
 #include "../h/systm.h"
+#include "../h/ioctl.h"
 #include "../h/tty.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/conf.h"
 #include "../h/tty.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/conf.h"
-#include "../h/buf.h"
 #include "../h/file.h"
 #include "../h/proc.h"
 #include "../h/file.h"
 #include "../h/proc.h"
+#include "../h/uio.h"
+#include "../h/kernel.h"
 
 #if NPTY == 1
 #undef NPTY
 
 #if NPTY == 1
 #undef NPTY
@@ -50,25 +52,22 @@ ptsopen(dev, flag)
 {
        register struct tty *tp;
 
 {
        register struct tty *tp;
 
-       if (minor(dev) >= NPTY) {
-               u.u_error = ENXIO;
-               return;
-       }
+       if (minor(dev) >= NPTY)
+               return (ENXIO);
        tp = &pt_tty[minor(dev)];
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);           /* Set up default chars */
        tp = &pt_tty[minor(dev)];
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);           /* Set up default chars */
+               tp->t_ispeed = tp->t_ospeed = EXTB;
                tp->t_flags = 0;        /* No features (nor raw mode) */
                tp->t_flags = 0;        /* No features (nor raw mode) */
-       } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) {
-               u.u_error = EBUSY;
-               return;
-       }
+       } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
+               return (EBUSY);
        if (tp->t_oproc)                        /* Ctrlr still around. */
                tp->t_state |= TS_CARR_ON;
        while ((tp->t_state & TS_CARR_ON) == 0) {
                tp->t_state |= TS_WOPEN;
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        if (tp->t_oproc)                        /* Ctrlr still around. */
                tp->t_state |= TS_CARR_ON;
        while ((tp->t_state & TS_CARR_ON) == 0) {
                tp->t_state |= TS_WOPEN;
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
-       (*linesw[tp->t_line].l_open)(dev, tp);
+       return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
 
 ptsclose(dev)
 }
 
 ptsclose(dev)
@@ -81,11 +80,13 @@ ptsclose(dev)
        ttyclose(tp);
 }
 
        ttyclose(tp);
 }
 
-ptsread(dev)
+ptsread(dev, uio)
        dev_t dev;
        dev_t dev;
+       struct uio *uio;
 {
        register struct tty *tp = &pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
 {
        register struct tty *tp = &pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
+       int error = 0;
 
 again:
        if (pti->pt_flags & PF_REMOTE) {
 
 again:
        if (pti->pt_flags & PF_REMOTE) {
@@ -96,33 +97,35 @@ again:
                            (u.u_procp->p_flag&SDETACH) ||
        */
                            u.u_procp->p_flag&SVFORK)
                            (u.u_procp->p_flag&SDETACH) ||
        */
                            u.u_procp->p_flag&SVFORK)
-                               return;
+                               return (EIO);
                        gsignal(u.u_procp->p_pgrp, SIGTTIN);
                        sleep((caddr_t)&lbolt, TTIPRI);
                }
                if (tp->t_rawq.c_cc == 0) {
                        gsignal(u.u_procp->p_pgrp, SIGTTIN);
                        sleep((caddr_t)&lbolt, TTIPRI);
                }
                if (tp->t_rawq.c_cc == 0) {
-                       if (tp->t_state & TS_NBIO) {
-                               u.u_error = EWOULDBLOCK;
-                               return;
-                       }
+                       if (tp->t_state & TS_NBIO)
+                               return (EWOULDBLOCK);
                        sleep((caddr_t)&tp->t_rawq, TTIPRI);
                        goto again;
                }
                        sleep((caddr_t)&tp->t_rawq, TTIPRI);
                        goto again;
                }
-               while (tp->t_rawq.c_cc > 1 && passc(getc(&tp->t_rawq)) >= 0)
-                       ;
+               while (tp->t_rawq.c_cc > 1 && uio->uio_resid > 0)
+                       if (ureadc(getc(&tp->t_rawq), uio) < 0) {
+                               error = EFAULT;
+                               break;
+                       }
                if (tp->t_rawq.c_cc == 1)
                        (void) getc(&tp->t_rawq);
                if (tp->t_rawq.c_cc)
                if (tp->t_rawq.c_cc == 1)
                        (void) getc(&tp->t_rawq);
                if (tp->t_rawq.c_cc)
-                       return;
+                       return (error);
        } else
                if (tp->t_oproc)
        } else
                if (tp->t_oproc)
-                       (*linesw[tp->t_line].l_read)(tp);
+                       error = (*linesw[tp->t_line].l_read)(tp, uio);
        wakeup((caddr_t)&tp->t_rawq.c_cf);
        if (pti->pt_selw) {
                selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL);
                pti->pt_selw = 0;
                pti->pt_flags &= ~PF_WCOLL;
        }
        wakeup((caddr_t)&tp->t_rawq.c_cf);
        if (pti->pt_selw) {
                selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL);
                pti->pt_selw = 0;
                pti->pt_flags &= ~PF_WCOLL;
        }
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -130,14 +133,16 @@ again:
  * Wakeups of controlling tty will happen
  * indirectly, when tty driver calls ptsstart.
  */
  * Wakeups of controlling tty will happen
  * indirectly, when tty driver calls ptsstart.
  */
-ptswrite(dev)
+ptswrite(dev, uio)
        dev_t dev;
        dev_t dev;
+       struct uio *uio;
 {
        register struct tty *tp;
 
        tp = &pt_tty[minor(dev)];
 {
        register struct tty *tp;
 
        tp = &pt_tty[minor(dev)];
-       if (tp->t_oproc)
-               (*linesw[tp->t_line].l_write)(tp);
+       if (tp->t_oproc == 0)
+               return (EIO);
+       return ((*linesw[tp->t_line].l_write)(tp, uio));
 }
 
 /*
 }
 
 /*
@@ -179,15 +184,11 @@ ptcopen(dev, flag)
        register struct tty *tp;
        struct pt_ioctl *pti;
 
        register struct tty *tp;
        struct pt_ioctl *pti;
 
-       if (minor(dev) >= NPTY) {
-               u.u_error = ENXIO;
-               return;
-       }
+       if (minor(dev) >= NPTY)
+               return (ENXIO);
        tp = &pt_tty[minor(dev)];
        tp = &pt_tty[minor(dev)];
-       if (tp->t_oproc) {
-               u.u_error = EIO;
-               return;
-       }
+       if (tp->t_oproc)
+               return (EIO);
        tp->t_oproc = ptsstart;
        if (tp->t_state & TS_WOPEN)
                wakeup((caddr_t)&tp->t_rawq);
        tp->t_oproc = ptsstart;
        if (tp->t_state & TS_WOPEN)
                wakeup((caddr_t)&tp->t_rawq);
@@ -195,6 +196,7 @@ ptcopen(dev, flag)
        pti = &pt_ioctl[minor(dev)];
        pti->pt_flags = 0;
        pti->pt_send = 0;
        pti = &pt_ioctl[minor(dev)];
        pti->pt_flags = 0;
        pti->pt_send = 0;
+       return (0);
 }
 
 ptcclose(dev)
 }
 
 ptcclose(dev)
@@ -206,37 +208,41 @@ ptcclose(dev)
        if (tp->t_state & TS_ISOPEN)
                gsignal(tp->t_pgrp, SIGHUP);
        tp->t_state &= ~TS_CARR_ON;     /* virtual carrier gone */
        if (tp->t_state & TS_ISOPEN)
                gsignal(tp->t_pgrp, SIGHUP);
        tp->t_state &= ~TS_CARR_ON;     /* virtual carrier gone */
-       flushtty(tp, FREAD|FWRITE);
+       ttyflush(tp, FREAD|FWRITE);
        tp->t_oproc = 0;                /* mark closed */
 }
 
        tp->t_oproc = 0;                /* mark closed */
 }
 
-ptcread(dev)
+ptcread(dev, uio)
        dev_t dev;
        dev_t dev;
+       struct uio *uio;
 {
 {
-       register struct tty *tp;
+       register struct tty *tp = &pt_tty[minor(dev)];
        struct pt_ioctl *pti;
        struct pt_ioctl *pti;
+       int error = 0;
 
 
-       tp = &pt_tty[minor(dev)];
        if ((tp->t_state&(TS_CARR_ON|TS_ISOPEN)) == 0)
        if ((tp->t_state&(TS_CARR_ON|TS_ISOPEN)) == 0)
-               return;
+               return (EIO);
        pti = &pt_ioctl[minor(dev)];
        if (pti->pt_flags & PF_PKT) {
                if (pti->pt_send) {
        pti = &pt_ioctl[minor(dev)];
        if (pti->pt_flags & PF_PKT) {
                if (pti->pt_send) {
-                       (void) passc(pti->pt_send);
+                       error = ureadc(pti->pt_send, uio);
+                       if (error)
+                               return (error);
                        pti->pt_send = 0;
                        pti->pt_send = 0;
-                       return;
+                       return (0);
                }
                }
-               (void) passc(0);
+               error = ureadc(0, uio);
        }
        while (tp->t_outq.c_cc == 0 || (tp->t_state&TS_TTSTOP)) {
        }
        while (tp->t_outq.c_cc == 0 || (tp->t_state&TS_TTSTOP)) {
-               if (pti->pt_flags&PF_NBIO) {
-                       u.u_error = EWOULDBLOCK;
-                       return;
-               }
+               if (pti->pt_flags&PF_NBIO)
+                       return (EWOULDBLOCK);
                sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI);
        }
                sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI);
        }
-       while (tp->t_outq.c_cc && passc(getc(&tp->t_outq)) >= 0)
-               ;
+       while (tp->t_outq.c_cc && uio->uio_resid > 0)
+               if (ureadc(getc(&tp->t_outq), uio) < 0) {
+                       error = EFAULT;
+                       break;
+               }
        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
@@ -248,6 +254,7 @@ ptcread(dev)
                        tp->t_state &= ~TS_WCOLL;
                }
        }
                        tp->t_state &= ~TS_WCOLL;
                }
        }
+       return (error);
 }
 
 ptsstop(tp, flush)
 }
 
 ptsstop(tp, flush)
@@ -307,33 +314,48 @@ ptcselect(dev, rw)
        return (0);
 }
 
        return (0);
 }
 
-ptcwrite(dev)
+ptcwrite(dev, uio)
        dev_t dev;
        dev_t dev;
+       struct uio *uio;
 {
 {
-       register struct tty *tp;
+       register struct tty *tp = &pt_tty[minor(dev)];
        register char *cp, *ce;
        register int cc;
        char locbuf[BUFSIZ];
        int cnt = 0;
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        register char *cp, *ce;
        register int cc;
        char locbuf[BUFSIZ];
        int cnt = 0;
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
+       int error = 0;
 
 
-       tp = &pt_tty[minor(dev)];
        if ((tp->t_state&(TS_CARR_ON|TS_ISOPEN)) == 0)
        if ((tp->t_state&(TS_CARR_ON|TS_ISOPEN)) == 0)
-               return;
+               return (EIO);
        do {
        do {
-               cc = MIN(u.u_count, BUFSIZ);
+               register struct iovec *iov;
+
+               if (uio->uio_iovcnt == 0)
+                       break;
+               iov = uio->uio_iov;
+               if (iov->iov_len == 0) {
+                       uio->uio_iovcnt--;      
+                       uio->uio_iov++;
+                       if (uio->uio_iovcnt < 0)
+                               panic("ptcwrite");
+                       continue;
+               }
+               cc = MIN(iov->iov_len, BUFSIZ);
                cp = locbuf;
                cp = locbuf;
-               iomove(cp, (unsigned)cc, B_WRITE);
-               if (u.u_error)
+               error = uiomove(cp, cc, UIO_WRITE, uio);
+               if (error)
                        break;
                ce = cp + cc;
 again:
                if (pti->pt_flags & PF_REMOTE) {
                        if (tp->t_rawq.c_cc) {
                                if (pti->pt_flags & PF_NBIO) {
                        break;
                ce = cp + cc;
 again:
                if (pti->pt_flags & PF_REMOTE) {
                        if (tp->t_rawq.c_cc) {
                                if (pti->pt_flags & PF_NBIO) {
-                                       u.u_count += ce - cp;
-                                       u.u_error = EWOULDBLOCK;
-                                       return;
+                                       iov->iov_base -= ce - cp;
+                                       iov->iov_len += ce - cp;
+                                       uio->uio_resid += ce - cp;
+                                       uio->uio_offset -= ce - cp;
+                                       return (EWOULDBLOCK);
                                }
                                sleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI);
                                goto again;
                                }
                                sleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI);
                                goto again;
@@ -341,16 +363,19 @@ again:
                        (void) b_to_q(cp, cc, &tp->t_rawq);
                        (void) putc(0, &tp->t_rawq);
                        wakeup((caddr_t)&tp->t_rawq);
                        (void) b_to_q(cp, cc, &tp->t_rawq);
                        (void) putc(0, &tp->t_rawq);
                        wakeup((caddr_t)&tp->t_rawq);
-                       return;
+                       return (0);
                }
                while (cp < ce) {
                        while (tp->t_delct && tp->t_rawq.c_cc >= TTYHOG - 2) {
                                wakeup((caddr_t)&tp->t_rawq);
                                if (tp->t_state & TS_NBIO) {
                }
                while (cp < ce) {
                        while (tp->t_delct && tp->t_rawq.c_cc >= TTYHOG - 2) {
                                wakeup((caddr_t)&tp->t_rawq);
                                if (tp->t_state & TS_NBIO) {
-                                       u.u_count += ce - cp;
+                                       iov->iov_base -= ce - cp;
+                                       iov->iov_len += ce - cp;
+                                       uio->uio_resid += ce - cp;
+                                       uio->uio_offset -= ce - cp;
                                        if (cnt == 0)
                                        if (cnt == 0)
-                                               u.u_error = EWOULDBLOCK;
-                                       return;
+                                               return (EWOULDBLOCK);
+                                       return (0);
                                }
                                /* Better than just flushing it! */
                                /* Wait for something to be read */
                                }
                                /* Better than just flushing it! */
                                /* Wait for something to be read */
@@ -360,63 +385,55 @@ again:
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
                        cnt++;
                }
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
                        cnt++;
                }
-       } while (u.u_count);
+       } while (uio->uio_resid);
+       return (error);
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-ptyioctl(dev, cmd, addr, flag)
-       caddr_t addr;
+ptyioctl(dev, cmd, data, flag)
+       caddr_t data;
        dev_t dev;
 {
        register struct tty *tp = &pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        dev_t dev;
 {
        register struct tty *tp = &pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
+       int error;
 
        /* IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG ??? */
 
        /* IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG ??? */
-       if (cdevsw[major(dev)].d_open == ptcopen) {
-               if (cmd == TIOCPKT) {
-                       int packet;
-                       if (copyin((caddr_t)addr, (caddr_t)&packet, sizeof (packet))) {
-                               u.u_error = EFAULT;
-                               return;
-                       }
-                       if (packet)
+       if (cdevsw[major(dev)].d_open == ptcopen)
+               switch (cmd) {
+
+               case TIOCPKT:
+                       if (*(int *)data)
                                pti->pt_flags |= PF_PKT;
                        else
                                pti->pt_flags &= ~PF_PKT;
                                pti->pt_flags |= PF_PKT;
                        else
                                pti->pt_flags &= ~PF_PKT;
-                       return;
-               }
-               if (cmd == TIOCREMOTE) {
-                       int remote;
-                       if (copyin((caddr_t)addr, (caddr_t)&remote, sizeof (remote))) {
-                               u.u_error = EFAULT;
-                               return;
-                       }
-                       if (remote)
+                       return (0);
+
+               case TIOCREMOTE:
+                       if (*(int *)data)
                                pti->pt_flags |= PF_REMOTE;
                        else
                                pti->pt_flags &= ~PF_REMOTE;
                                pti->pt_flags |= PF_REMOTE;
                        else
                                pti->pt_flags &= ~PF_REMOTE;
-                       flushtty(tp, FREAD|FWRITE);
-                       return;
-               }
-               if (cmd == FIONBIO) {
-                       int nbio;
-                       if (copyin((caddr_t)addr, (caddr_t)&nbio, sizeof (nbio))) {
-                               u.u_error = EFAULT;
-                               return;
-                       }
-                       if (nbio)
+                       ttyflush(tp, FREAD|FWRITE);
+                       return (0);
+
+               case FIONBIO:
+                       if (*(int *)data)
                                pti->pt_flags |= PF_NBIO;
                        else
                                pti->pt_flags &= ~PF_NBIO;
                                pti->pt_flags |= PF_NBIO;
                        else
                                pti->pt_flags &= ~PF_NBIO;
-                       return;
+                       return (0);
+
+               case TIOCSETP:
+                       while (getc(&tp->t_outq) >= 0)
+                               ;
+                       break;
                }
                }
-               if (cmd == TIOCSETP)
-                       while (getc(&tp->t_outq) >= 0);
-       }
-       if (ttioctl(tp, cmd, addr, dev) == 0)
-               u.u_error = ENOTTY;
-       { int stop = (tp->t_un.t_chr.t_stopc == ('s'&037) &&
-                     tp->t_un.t_chr.t_startc == ('q'&037));
+       error = ttioctl(tp, cmd, data, dev);
+       if (error < 0)
+               error = ENOTTY;
+       { int stop = (tp->t_stopc == ('s'&037) &&
+                     tp->t_startc == ('q'&037));
        if (pti->pt_flags & PF_NOSTOP) {
                if (stop) {
                        pti->pt_send &= TIOCPKT_NOSTOP;
        if (pti->pt_flags & PF_NOSTOP) {
                if (stop) {
                        pti->pt_send &= TIOCPKT_NOSTOP;
@@ -433,5 +450,6 @@ ptyioctl(dev, cmd, addr, flag)
                }
        }
        }
                }
        }
        }
+       return (error);
 }
 #endif
 }
 #endif