Eliminated the "physstrat" wart and merged it into kern_physio.c. This
[unix-history] / sys / kern / tty_pty.c
index 7a10916..419bcf4 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: tty_pty.c,v 1.5 1993/11/25 01:33:29 wollman Exp $
+ *     $Id: tty_pty.c,v 1.9 1994/01/29 04:04:26 davidg Exp $
  */
 
 /*
  */
 
 /*
@@ -66,7 +66,7 @@ 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;
@@ -75,13 +75,15 @@ 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*/
 int
 
 /*ARGSUSED*/
 int
@@ -99,7 +101,7 @@ 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) {
                tp->t_state |= TS_WOPEN;
                ttychars(tp);           /* Set up default chars */
        if ((tp->t_state & TS_ISOPEN) == 0) {
                tp->t_state |= TS_WOPEN;
                ttychars(tp);           /* Set up default chars */
@@ -117,12 +119,13 @@ ptsopen(dev, flag, devtype, p)
                tp->t_state |= TS_WOPEN;
                if (flag&FNONBLOCK)
                        break;
                tp->t_state |= TS_WOPEN;
                if (flag&FNONBLOCK)
                        break;
-               if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
+               if (error = ttysleep(tp, (caddr_t)tp->t_raw, TTIPRI | PCATCH,
                    ttopen, 0))
                        return (error);
        }
        error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
        ptcwakeup(tp, FREAD|FWRITE);
                    ttopen, 0))
                        return (error);
        }
        error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
        ptcwakeup(tp, FREAD|FWRITE);
+       pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN;
        return (error);
 }
 
        return (error);
 }
 
@@ -134,10 +137,17 @@ ptsclose(dev, flag, mode, p)
 {
        register struct tty *tp;
 
 {
        register struct tty *tp;
 
-       tp = &pt_tty[minor(dev)];
+       tp = pt_tty[minor(dev)];
        (*linesw[tp->t_line].l_close)(tp, flag);
        ttyclose(tp);
        ptcwakeup(tp, FREAD|FWRITE);
        (*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);
 }
 
@@ -148,7 +158,7 @@ ptsread(dev, uio, flag)
        int flag;
 {
        struct proc *p = curproc;
        int flag;
 {
        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;
 
@@ -165,22 +175,22 @@ again:
                            TTIPRI | PCATCH, ttybg, 0))
                                return (error);
                }
                            TTIPRI | PCATCH, ttybg, 0))
                                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,
+                       if (error = ttysleep(tp, (caddr_t)tp->t_can,
                            TTIPRI | PCATCH, ttyin, 0))
                                return (error);
                        goto again;
                }
                            TTIPRI | PCATCH, ttyin, 0))
                                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)
@@ -202,7 +212,7 @@ ptswrite(dev, uio, 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));
@@ -240,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((caddr_t)&tp->t_out->rb_tl);
        }
        if (flag & FWRITE) {
                if (pti->pt_selw) {
        }
        if (flag & FWRITE) {
                if (pti->pt_selw) {
@@ -248,7 +258,7 @@ 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((caddr_t)&tp->t_raw->rb_hd);
        }
 }
 
        }
 }
 
@@ -268,14 +278,15 @@ 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);
        pti->pt_send = 0;
        pti->pt_ucntl = 0;
        return (0);
@@ -289,16 +300,22 @@ ptcclose(dev)
 {
        register struct tty *tp;
 
 {
        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);
 }
 
@@ -308,7 +325,7 @@ ptcread(dev, uio, flag)
        struct uio *uio;
        int flag;
 {
        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;
@@ -340,14 +357,14 @@ 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,
+               if (error = tsleep((caddr_t)&tp->t_out->rb_tl, TTIPRI | PCATCH,
                    ttyin, 0))
                        return (error);
        }
                    ttyin, 0))
                        return (error);
        }
@@ -357,21 +374,21 @@ 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 (RB_LEN(tp->t_out) <= tp->t_lowat) {
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
-                       wakeup((caddr_t)&tp->t_out);
+                       wakeup((caddr_t)tp->t_out);
                }
                if (tp->t_wsel) {
                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
                }
                if (tp->t_wsel) {
                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
@@ -412,7 +429,7 @@ ptcselect(dev, rw, p)
        int rw;
        struct proc *p;
 {
        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;
@@ -427,7 +444,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);
                }
@@ -449,12 +466,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);
                        }
                }
@@ -474,7 +491,7 @@ ptcwrite(dev, uio, flag)
        register struct uio *uio;
        int flag;
 {
        register struct uio *uio;
        int flag;
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
+       register struct tty *tp = pt_tty[minor(dev)];
        register u_char *cp = 0;
        register int cc = 0;
        u_char locbuf[BUFSIZ];
        register u_char *cp = 0;
        register int cc = 0;
        u_char locbuf[BUFSIZ];
@@ -486,12 +503,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)
@@ -505,16 +522,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) {
@@ -529,9 +546,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((caddr_t)tp->t_raw);
                                goto block;
                        }
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
                                goto block;
                        }
                        (*linesw[tp->t_line].l_rint)(*cp++, tp);
@@ -555,7 +572,7 @@ block:
                        return (EWOULDBLOCK);
                return (0);
        }
                        return (EWOULDBLOCK);
                return (0);
        }
-       if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH,
+       if (error = tsleep((caddr_t)&tp->t_raw->rb_hd, TTOPRI | PCATCH,
            ttyout, 0)) {
                /* adjust for data copied in but not written */
                uio->uio_resid += cc;
            ttyout, 0)) {
                /* adjust for data copied in but not written */
                uio->uio_resid += cc;
@@ -572,7 +589,7 @@ ptyioctl(dev, cmd, data, flag)
        dev_t dev;
        int flag;
 {
        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;
@@ -649,7 +666,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;