make sure that the pseudo_set isn't empty.
[unix-history] / sys / kern / tty_pty.c
index 8642c01..bc5bb54 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)tty_pty.c     7.21 (Berkeley) 5/30/91
  * SUCH DAMAGE.
  *
  *     from: @(#)tty_pty.c     7.21 (Berkeley) 5/30/91
- *     $Id$
+ *     $Id: tty_pty.c,v 1.13 1994/04/20 18:37:10 ache Exp $
  */
 
 /*
  */
 
 /*
@@ -51,6 +51,7 @@
 #include "uio.h"
 #include "kernel.h"
 #include "vnode.h"
 #include "uio.h"
 #include "kernel.h"
 #include "vnode.h"
+#include "signalvar.h"
 
 #if NPTY == 1
 #undef NPTY
 
 #if NPTY == 1
 #undef NPTY
 
 #define BUFSIZ 100             /* Chunk size iomoved to/from user */
 
 
 #define BUFSIZ 100             /* Chunk size iomoved to/from user */
 
+static void ptcwakeup(struct tty *, int);
+
 /*
  * pts == /dev/tty[pqrs]?
  * ptc == /dev/pty[pqrs]?
  */
 /*
  * pts == /dev/tty[pqrs]?
  * ptc == /dev/pty[pqrs]?
  */
-struct tty pt_tty[NPTY];
+struct tty *pt_tty[NPTY];
 struct pt_ioctl {
        int     pt_flags;
        pid_t   pt_selr, pt_selw;
 struct pt_ioctl {
        int     pt_flags;
        pid_t   pt_selr, pt_selw;
@@ -72,17 +75,22 @@ struct      pt_ioctl {
 } pt_ioctl[NPTY];
 int    npty = NPTY;            /* for pstat -t */
 
 } pt_ioctl[NPTY];
 int    npty = NPTY;            /* for pstat -t */
 
-#define        PF_RCOLL        0x01
-#define        PF_WCOLL        0x02
-#define        PF_PKT          0x08            /* packet mode */
-#define        PF_STOPPED      0x10            /* user told stopped */
-#define        PF_REMOTE       0x20            /* remote and flow controlled input */
-#define        PF_NOSTOP       0x40
-#define PF_UCNTL       0x80            /* user control mode */
+#define        PF_RCOLL        0x0001
+#define        PF_WCOLL        0x0002
+#define        PF_PKT          0x0008          /* packet mode */
+#define        PF_STOPPED      0x0010          /* user told stopped */
+#define        PF_REMOTE       0x0020          /* remote and flow controlled input */
+#define        PF_NOSTOP       0x0040
+#define PF_UCNTL       0x0080          /* user control mode */
+#define        PF_COPEN        0x0100          /* master open */
+#define        PF_SOPEN        0x0200          /* slave open */
 
 /*ARGSUSED*/
 
 /*ARGSUSED*/
+int
 ptsopen(dev, flag, devtype, p)
        dev_t dev;
 ptsopen(dev, flag, devtype, p)
        dev_t dev;
+       int flag;
+       int devtype;
        struct proc *p;
 {
        register struct tty *tp;
        struct proc *p;
 {
        register struct tty *tp;
@@ -93,9 +101,8 @@ ptsopen(dev, flag, devtype, p)
 #endif
        if (minor(dev) >= NPTY)
                return (ENXIO);
 #endif
        if (minor(dev) >= NPTY)
                return (ENXIO);
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]);
        if ((tp->t_state & TS_ISOPEN) == 0) {
        if ((tp->t_state & TS_ISOPEN) == 0) {
-               tp->t_state |= TS_WOPEN;
                ttychars(tp);           /* Set up default chars */
                tp->t_iflag = TTYDEF_IFLAG;
                tp->t_oflag = TTYDEF_OFLAG;
                ttychars(tp);           /* Set up default chars */
                tp->t_iflag = TTYDEF_IFLAG;
                tp->t_oflag = TTYDEF_OFLAG;
@@ -108,18 +115,21 @@ ptsopen(dev, flag, devtype, p)
        if (tp->t_oproc)                        /* Ctrlr still around. */
                tp->t_state |= TS_CARR_ON;
        while ((tp->t_state & TS_CARR_ON) == 0) {
        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;
                if (flag&FNONBLOCK)
                        break;
                if (flag&FNONBLOCK)
                        break;
-               if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
-                   ttopen, 0))
+               if (error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
+                   "ptsopn", 0))
                        return (error);
        }
        error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
                        return (error);
        }
        error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
-       ptcwakeup(tp, FREAD|FWRITE);
+       if (error == 0) {
+               ptcwakeup(tp, FREAD|FWRITE);
+               pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN;
+       }
        return (error);
 }
 
        return (error);
 }
 
+int
 ptsclose(dev, flag, mode, p)
        dev_t dev;
        int flag, mode;
 ptsclose(dev, flag, mode, p)
        dev_t dev;
        int flag, mode;
@@ -127,19 +137,28 @@ ptsclose(dev, flag, mode, p)
 {
        register struct tty *tp;
 
 {
        register struct tty *tp;
 
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)];
+       ptcwakeup(tp, FREAD|FWRITE);
        (*linesw[tp->t_line].l_close)(tp, flag);
        ttyclose(tp);
        (*linesw[tp->t_line].l_close)(tp, flag);
        ttyclose(tp);
-       ptcwakeup(tp, FREAD|FWRITE);
+       pt_ioctl[minor(dev)].pt_flags &= ~PF_SOPEN;
+       if ((pt_ioctl[minor(dev)].pt_flags & PF_COPEN) == 0) {
+               ttyfree(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+               pt_tty[minor(dev)] = (struct tty *)NULL;
+#endif
+       }
        return(0);
 }
 
        return(0);
 }
 
+int
 ptsread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 ptsread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
        struct proc *p = curproc;
 {
        struct proc *p = curproc;
-       register struct tty *tp = &pt_tty[minor(dev)];
+       register struct tty *tp = pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        int error = 0;
 
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        int error = 0;
 
@@ -153,25 +172,25 @@ again:
                                return (EIO);
                        pgsignal(p->p_pgrp, SIGTTIN, 1);
                        if (error = ttysleep(tp, (caddr_t)&lbolt, 
                                return (EIO);
                        pgsignal(p->p_pgrp, SIGTTIN, 1);
                        if (error = ttysleep(tp, (caddr_t)&lbolt, 
-                           TTIPRI | PCATCH, ttybg, 0))
+                           TTIPRI | PCATCH, "ptsbg", 0))
                                return (error);
                }
                                return (error);
                }
-               if (RB_LEN(&tp->t_can) == 0) {
+               if (RB_LEN(tp->t_can) == 0) {
                        if (flag & IO_NDELAY)
                                return (EWOULDBLOCK);
                        if (flag & IO_NDELAY)
                                return (EWOULDBLOCK);
-                       if (error = ttysleep(tp, (caddr_t)&tp->t_can,
-                           TTIPRI | PCATCH, ttyin, 0))
+                       if (error = ttysleep(tp, (caddr_t)tp->t_can,
+                           TTIPRI | PCATCH, "ptsin", 0))
                                return (error);
                        goto again;
                }
                                return (error);
                        goto again;
                }
-               while (RB_LEN(&tp->t_can) > 1 && uio->uio_resid > 0)
-                       if (ureadc(getc(&tp->t_can), uio) < 0) {
+               while (RB_LEN(tp->t_can) > 1 && uio->uio_resid > 0)
+                       if (ureadc(getc(tp->t_can), uio) < 0) {
                                error = EFAULT;
                                break;
                        }
                                error = EFAULT;
                                break;
                        }
-               if (RB_LEN(&tp->t_can) == 1)
-                       (void) getc(&tp->t_can);
-               if (RB_LEN(&tp->t_can))
+               if (RB_LEN(tp->t_can) == 1)
+                       (void) getc(tp->t_can);
+               if (RB_LEN(tp->t_can))
                        return (error);
        } else
                if (tp->t_oproc)
                        return (error);
        } else
                if (tp->t_oproc)
@@ -185,13 +204,15 @@ 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.
  */
+int
 ptswrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 ptswrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
        register struct tty *tp;
 
 {
        register struct tty *tp;
 
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)];
        if (tp->t_oproc == 0)
                return (EIO);
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        if (tp->t_oproc == 0)
                return (EIO);
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
@@ -201,6 +222,7 @@ ptswrite(dev, uio, flag)
  * Start output on pseudo-tty.
  * Wake up process selecting or sleeping for input from controlling tty.
  */
  * Start output on pseudo-tty.
  * Wake up process selecting or sleeping for input from controlling tty.
  */
+void
 ptsstart(tp)
        struct tty *tp;
 {
 ptsstart(tp)
        struct tty *tp;
 {
@@ -215,8 +237,10 @@ ptsstart(tp)
        ptcwakeup(tp, FREAD);
 }
 
        ptcwakeup(tp, FREAD);
 }
 
+static void
 ptcwakeup(tp, flag)
        struct tty *tp;
 ptcwakeup(tp, flag)
        struct tty *tp;
+       int flag;
 {
        struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
 
 {
        struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
 
@@ -226,7 +250,7 @@ ptcwakeup(tp, flag)
                        pti->pt_selr = 0;
                        pti->pt_flags &= ~PF_RCOLL;
                }
                        pti->pt_selr = 0;
                        pti->pt_flags &= ~PF_RCOLL;
                }
-               wakeup((caddr_t)&tp->t_out.rb_tl);
+               wakeup(TSA_PTC_READ(tp));
        }
        if (flag & FWRITE) {
                if (pti->pt_selw) {
        }
        if (flag & FWRITE) {
                if (pti->pt_selw) {
@@ -234,13 +258,14 @@ ptcwakeup(tp, flag)
                        pti->pt_selw = 0;
                        pti->pt_flags &= ~PF_WCOLL;
                }
                        pti->pt_selw = 0;
                        pti->pt_flags &= ~PF_WCOLL;
                }
-               wakeup((caddr_t)&tp->t_raw.rb_hd);
+               wakeup(TSA_PTC_WRITE(tp));
        }
 }
 
 /*ARGSUSED*/
        }
 }
 
 /*ARGSUSED*/
+int
 #ifdef __STDC__
 #ifdef __STDC__
-ptcopen(dev_t dev, int flag, int devtype, struct proc *p)
+ptcopen(int /*dev_t*/ dev, int flag, int devtype, struct proc *p)
 #else
 ptcopen(dev, flag, devtype, p)
        dev_t dev;
 #else
 ptcopen(dev, flag, devtype, p)
        dev_t dev;
@@ -253,43 +278,54 @@ ptcopen(dev, flag, devtype, p)
 
        if (minor(dev) >= NPTY)
                return (ENXIO);
 
        if (minor(dev) >= NPTY)
                return (ENXIO);
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]);
        if (tp->t_oproc)
                return (EIO);
        tp->t_oproc = ptsstart;
        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        tp->t_lflag &= ~EXTPROC;
        pti = &pt_ioctl[minor(dev)];
        if (tp->t_oproc)
                return (EIO);
        tp->t_oproc = ptsstart;
        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        tp->t_lflag &= ~EXTPROC;
        pti = &pt_ioctl[minor(dev)];
-       pti->pt_flags = 0;
+       pti->pt_flags &= PF_SOPEN;
+       pti->pt_flags |= PF_COPEN;
        pti->pt_send = 0;
        pti->pt_ucntl = 0;
        return (0);
 }
 
 extern struct tty *constty;    /* -hv- 06.Oct.92*/
        pti->pt_send = 0;
        pti->pt_ucntl = 0;
        return (0);
 }
 
 extern struct tty *constty;    /* -hv- 06.Oct.92*/
+
+int
 ptcclose(dev)
        dev_t dev;
 {
        register struct tty *tp;
 
 ptcclose(dev)
        dev_t dev;
 {
        register struct tty *tp;
 
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)];
        (void)(*linesw[tp->t_line].l_modem)(tp, 0);
        tp->t_state &= ~TS_CARR_ON;
        tp->t_oproc = 0;                /* mark closed */
        tp->t_session = 0;
 
        (void)(*linesw[tp->t_line].l_modem)(tp, 0);
        tp->t_state &= ~TS_CARR_ON;
        tp->t_oproc = 0;                /* mark closed */
        tp->t_session = 0;
 
-/* XXX -hv- 6.Oct.92 this prevents the "hanging console bug" with X11 */
        if (constty==tp)
                constty = 0;
 
        if (constty==tp)
                constty = 0;
 
+       pt_ioctl[minor(dev)].pt_flags &= ~PF_COPEN;
+       if ((pt_ioctl[minor(dev)].pt_flags & PF_SOPEN) == 0) {
+               ttyfree(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+               pt_tty[minor(dev)] = (struct tty *)NULL;
+#endif
+       }
        return (0);
 }
 
        return (0);
 }
 
+int
 ptcread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 ptcread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
+       int flag;
 {
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
+       register struct tty *tp = pt_tty[minor(dev)];
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        char buf[BUFSIZ];
        int error = 0, cc;
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        char buf[BUFSIZ];
        int error = 0, cc;
@@ -321,15 +357,15 @@ ptcread(dev, uio, flag)
                                pti->pt_ucntl = 0;
                                return (0);
                        }
                                pti->pt_ucntl = 0;
                                return (0);
                        }
-                       if (RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0)
+                       if (RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0)
                                break;
                }
                if ((tp->t_state&TS_CARR_ON) == 0)
                        return (0);     /* EOF */
                if (flag & IO_NDELAY)
                        return (EWOULDBLOCK);
                                break;
                }
                if ((tp->t_state&TS_CARR_ON) == 0)
                        return (0);     /* EOF */
                if (flag & IO_NDELAY)
                        return (EWOULDBLOCK);
-               if (error = tsleep((caddr_t)&tp->t_out.rb_tl, TTIPRI | PCATCH,
-                   ttyin, 0))
+               if (error = tsleep(TSA_PTC_READ(tp), TTIPRI | PCATCH,
+                   "ptcin", 0))
                        return (error);
        }
        if (pti->pt_flags & (PF_PKT|PF_UCNTL))
                        return (error);
        }
        if (pti->pt_flags & (PF_PKT|PF_UCNTL))
@@ -338,31 +374,23 @@ ptcread(dev, uio, flag)
 #ifdef was
                cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ));
 #else
 #ifdef was
                cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ));
 #else
-               cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(&tp->t_out));
+               cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(tp->t_out));
                if (cc) {
                if (cc) {
-                       bcopy(tp->t_out.rb_hd, buf, cc);
-                       tp->t_out.rb_hd =
-                               RB_ROLLOVER(&tp->t_out, tp->t_out.rb_hd+cc);
+                       bcopy(tp->t_out->rb_hd, buf, cc);
+                       tp->t_out->rb_hd =
+                               RB_ROLLOVER(tp->t_out, tp->t_out->rb_hd+cc);
                }
 #endif
                if (cc <= 0)
                        break;
                error = uiomove(buf, cc, uio);
        }
                }
 #endif
                if (cc <= 0)
                        break;
                error = uiomove(buf, cc, uio);
        }
-       if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
-               if (tp->t_state&TS_ASLEEP) {
-                       tp->t_state &= ~TS_ASLEEP;
-                       wakeup((caddr_t)&tp->t_out);
-               }
-               if (tp->t_wsel) {
-                       selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
-                       tp->t_wsel = 0;
-                       tp->t_state &= ~TS_WCOLL;
-               }
-       }
+       if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
+               ttwwakeup(tp);
        return (error);
 }
 
        return (error);
 }
 
+void
 ptsstop(tp, flush)
        register struct tty *tp;
        int flush;
 ptsstop(tp, flush)
        register struct tty *tp;
        int flush;
@@ -386,12 +414,13 @@ ptsstop(tp, flush)
        ptcwakeup(tp, flag);
 }
 
        ptcwakeup(tp, flag);
 }
 
+int
 ptcselect(dev, rw, p)
        dev_t dev;
        int rw;
        struct proc *p;
 {
 ptcselect(dev, rw, p)
        dev_t dev;
        int rw;
        struct proc *p;
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
+       register struct tty *tp = pt_tty[minor(dev)];
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        struct proc *prev;
        int s;
        struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        struct proc *prev;
        int s;
@@ -406,7 +435,7 @@ ptcselect(dev, rw, p)
                 */
                s = spltty();
                if ((tp->t_state&TS_ISOPEN) &&
                 */
                s = spltty();
                if ((tp->t_state&TS_ISOPEN) &&
-                    RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) {
+                    RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) {
                        splx(s);
                        return (1);
                }
                        splx(s);
                        return (1);
                }
@@ -428,12 +457,12 @@ ptcselect(dev, rw, p)
        case FWRITE:
                if (tp->t_state&TS_ISOPEN) {
                        if (pti->pt_flags & PF_REMOTE) {
        case FWRITE:
                if (tp->t_state&TS_ISOPEN) {
                        if (pti->pt_flags & PF_REMOTE) {
-                           if (RB_LEN(&tp->t_can) == 0)
+                           if (RB_LEN(tp->t_can) == 0)
                                return (1);
                        } else {
                                return (1);
                        } else {
-                           if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can) < TTYHOG-2)
+                           if (RB_LEN(tp->t_raw) + RB_LEN(tp->t_can) < TTYHOG-2)
                                    return (1);
                                    return (1);
-                           if (RB_LEN(&tp->t_can) == 0 && (tp->t_iflag&ICANON))
+                           if (RB_LEN(tp->t_can) == 0 && (tp->t_iflag&ICANON))
                                    return (1);
                        }
                }
                                    return (1);
                        }
                }
@@ -447,12 +476,14 @@ ptcselect(dev, rw, p)
        return (0);
 }
 
        return (0);
 }
 
+int
 ptcwrite(dev, uio, flag)
        dev_t dev;
        register struct uio *uio;
 ptcwrite(dev, uio, flag)
        dev_t dev;
        register struct uio *uio;
+       int flag;
 {
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
-       register u_char *cp;
+       register struct tty *tp = pt_tty[minor(dev)];
+       register u_char *cp = 0;
        register int cc = 0;
        u_char locbuf[BUFSIZ];
        int cnt = 0;
        register int cc = 0;
        u_char locbuf[BUFSIZ];
        int cnt = 0;
@@ -463,12 +494,12 @@ again:
        if ((tp->t_state&TS_ISOPEN) == 0)
                goto block;
        if (pti->pt_flags & PF_REMOTE) {
        if ((tp->t_state&TS_ISOPEN) == 0)
                goto block;
        if (pti->pt_flags & PF_REMOTE) {
-               if (RB_LEN(&tp->t_can))
+               if (RB_LEN(tp->t_can))
                        goto block;
                        goto block;
-               while (uio->uio_resid > 0 && RB_LEN(&tp->t_can) < TTYHOG - 1) {
+               while (uio->uio_resid > 0 && RB_LEN(tp->t_can) < TTYHOG - 1) {
                        if (cc == 0) {
                                cc = min(uio->uio_resid, BUFSIZ);
                        if (cc == 0) {
                                cc = min(uio->uio_resid, BUFSIZ);
-                               cc = min(cc, RB_CONTIGPUT(&tp->t_can));
+                               cc = min(cc, RB_CONTIGPUT(tp->t_can));
                                cp = locbuf;
                                error = uiomove((caddr_t)cp, cc, uio);
                                if (error)
                                cp = locbuf;
                                error = uiomove((caddr_t)cp, cc, uio);
                                if (error)
@@ -482,16 +513,16 @@ again:
                                (void) b_to_q((char *)cp, cc, &tp->t_canq);
 #else
                        if (cc) {
                                (void) b_to_q((char *)cp, cc, &tp->t_canq);
 #else
                        if (cc) {
-                               bcopy(cp, tp->t_can.rb_tl, cc);
-                               tp->t_can.rb_tl =
-                                 RB_ROLLOVER(&tp->t_can, tp->t_can.rb_tl+cc);
+                               bcopy(cp, tp->t_can->rb_tl, cc);
+                               tp->t_can->rb_tl =
+                                 RB_ROLLOVER(tp->t_can, tp->t_can->rb_tl+cc);
                        }
 #endif
                        cc = 0;
                }
                        }
 #endif
                        cc = 0;
                }
-               (void) putc(0, &tp->t_can);
+               (void) putc(0, tp->t_can);
                ttwakeup(tp);
                ttwakeup(tp);
-               wakeup((caddr_t)&tp->t_can);
+               wakeup((caddr_t)tp->t_can);
                return (0);
        }
        while (uio->uio_resid > 0) {
                return (0);
        }
        while (uio->uio_resid > 0) {
@@ -506,9 +537,9 @@ again:
                                return (EIO);
                }
                while (cc > 0) {
                                return (EIO);
                }
                while (cc > 0) {
-                       if ((RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can)) >= TTYHOG - 2 &&
-                          (RB_LEN(&tp->t_can) > 0 || !(tp->t_iflag&ICANON))) {
-                               wakeup((caddr_t)&tp->t_raw);
+                       if ((RB_LEN(tp->t_raw) + RB_LEN(tp->t_can)) >= TTYHOG - 2 &&
+                          (RB_LEN(tp->t_can) > 0 || !(tp->t_iflag&ICANON))) {
+                               wakeup(TSA_HUP_OR_INPUT(tp));
                                goto block;
                        }
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
                                goto block;
                        }
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
@@ -532,8 +563,8 @@ block:
                        return (EWOULDBLOCK);
                return (0);
        }
                        return (EWOULDBLOCK);
                return (0);
        }
-       if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH,
-           ttyout, 0)) {
+       if (error = tsleep(TSA_PTC_WRITE(tp), TTOPRI | PCATCH,
+           "ptcout", 0)) {
                /* adjust for data copied in but not written */
                uio->uio_resid += cc;
                return (error);
                /* adjust for data copied in but not written */
                uio->uio_resid += cc;
                return (error);
@@ -542,15 +573,17 @@ block:
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
+int
 ptyioctl(dev, cmd, data, flag)
        caddr_t data;
 ptyioctl(dev, cmd, data, flag)
        caddr_t data;
+       int cmd;
        dev_t dev;
        dev_t dev;
+       int flag;
 {
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
+       register struct tty *tp = pt_tty[minor(dev)];
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        register u_char *cc = tp->t_cc;
        int stop, error;
        register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
        register u_char *cc = tp->t_cc;
        int stop, error;
-       extern ttyinput();
 
        /*
         * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
 
        /*
         * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
@@ -624,7 +657,7 @@ ptyioctl(dev, cmd, data, flag)
                case TIOCSETA:
                case TIOCSETAW:
                case TIOCSETAF:
                case TIOCSETA:
                case TIOCSETAW:
                case TIOCSETAF:
-                       while (getc(&tp->t_out) >= 0)
+                       while (getc(tp->t_out) >= 0)
                                ;
                        break;
 
                                ;
                        break;