BSD 4_4 release
[unix-history] / usr / src / sys / kern / tty_pty.c
index a9a4033..e7d202b 100644 (file)
@@ -1,10 +1,36 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)tty_pty.c   7.29 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)tty_pty.c   8.1 (Berkeley) 6/30/93
  */
 
 /*
  */
 
 /*
@@ -23,7 +49,6 @@
 #include <sys/uio.h>
 #include <sys/kernel.h>
 #include <sys/vnode.h>
 #include <sys/uio.h>
 #include <sys/kernel.h>
 #include <sys/vnode.h>
-#include "tsleep.h"
 
 #if NPTY == 1
 #undef NPTY
 
 #if NPTY == 1
 #undef NPTY
@@ -42,23 +67,14 @@ struct      pt_ioctl {
        struct  selinfo pt_selr, pt_selw;
        u_char  pt_send;
        u_char  pt_ucntl;
        struct  selinfo pt_selr, pt_selw;
        u_char  pt_send;
        u_char  pt_ucntl;
-       struct  clist pt_ioc;
 } pt_ioctl[NPTY];              /* XXX */
 int    npty = NPTY;            /* for pstat -t */
 
 } pt_ioctl[NPTY];              /* XXX */
 int    npty = NPTY;            /* for pstat -t */
 
-#define        PF_RCOLL        0x0001
-#define        PF_WCOLL        0x0002
-#define        PF_NBIO         0x0004
-#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_TIOC         0x0100          /* transparent control mode */
-#define        PF_LIOC         0x0200          /* transparent control locked */
-#define        PF_WIOC         0x0400          /* waiting for PF_LIOC to clear */
-#define        PF_BLOCK        0x0800          /* block writes to slave */
-#define        PF_OWAIT        0x1000          /* waiting for PF_BLOCK to clear */
+#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 */
 
 void   ptsstop __P((struct tty *, int));
 
 
 void   ptsstop __P((struct tty *, int));
 
@@ -140,7 +156,6 @@ ptsclose(dev, flag, mode, p)
        err |= ttyclose(tp);
        ptcwakeup(tp, FREAD|FWRITE);
        return (err);
        err |= ttyclose(tp);
        ptcwakeup(tp, FREAD|FWRITE);
        return (err);
-       return (0);
 }
 
 ptsread(dev, uio, flag)
 }
 
 ptsread(dev, uio, flag)
@@ -200,17 +215,11 @@ ptswrite(dev, uio, flag)
        struct uio *uio;
        int flag;
 {
        struct uio *uio;
        int flag;
 {
-       register struct tty *tp = &pt_tty[minor(dev)];
-       register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
+       register struct tty *tp;
 
 
+       tp = &pt_tty[minor(dev)];
        if (tp->t_oproc == 0)
                return (EIO);
        if (tp->t_oproc == 0)
                return (EIO);
-
-       while (pti->pt_flags & PF_BLOCK) {
-               pti->pt_flags |= PF_OWAIT;
-               sleep((caddr_t)pti + 1, TTOPRI);
-       }
-
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
 
        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
 
@@ -291,7 +300,6 @@ ptcclose(dev)
        tp->t_oproc = 0;                /* mark closed */
        tp->t_session = 0;
        return (0);
        tp->t_oproc = 0;                /* mark closed */
        tp->t_session = 0;
        return (0);
-       return (0);
 }
 
 ptcread(dev, uio, flag)
 }
 
 ptcread(dev, uio, flag)
@@ -331,19 +339,6 @@ ptcread(dev, uio, flag)
                                pti->pt_ucntl = 0;
                                return (0);
                        }
                                pti->pt_ucntl = 0;
                                return (0);
                        }
-                       if (pti->pt_flags&PF_TIOC && pti->pt_ioc.c_cc) {
-                               if (uio->uio_resid < pti->pt_ioc.c_cc + 1)
-                                       return (E2BIG);
-                               error = ureadc(TIOCPKT_TIOC, uio);
-                               while (error == 0 && pti->pt_ioc.c_cc > 0) {
-                                       cc = q_to_b(&pti->pt_ioc, buf,
-                                           MIN(pti->pt_ioc.c_cc, BUFSIZ));
-                                       if (cc <= 0)    /* impossible? */
-                                               break;
-                                       error = uiomove(buf, cc, UIO_READ, uio);
-                               }
-                               return (error);
-                       }
                        if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
                                break;
                }
                        if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
                                break;
                }
@@ -355,7 +350,7 @@ ptcread(dev, uio, flag)
                    ttyin, 0))
                        return (error);
        }
                    ttyin, 0))
                        return (error);
        }
-       if (pti->pt_flags & (PF_PKT|PF_UCNTL|PF_TIOC))
+       if (pti->pt_flags & (PF_PKT|PF_UCNTL))
                error = ureadc(0, uio);
        while (uio->uio_resid > 0 && error == 0) {
                cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ));
                error = ureadc(0, uio);
        while (uio->uio_resid > 0 && error == 0) {
                cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ));
@@ -363,26 +358,17 @@ ptcread(dev, uio, flag)
                        break;
                error = uiomove(buf, cc, uio);
        }
                        break;
                error = uiomove(buf, cc, uio);
        }
-       if (tp->t_outq.c_cc <= TTLOWAT(tp) && !(pti->pt_flags & PF_BLOCK))
-               ptswake(tp);
+       if (tp->t_outq.c_cc <= tp->t_lowat) {
+               if (tp->t_state&TS_ASLEEP) {
+                       tp->t_state &= ~TS_ASLEEP;
+                       wakeup((caddr_t)&tp->t_outq);
+               }
+               selwakeup(&tp->t_wsel);
+       }
        return (error);
 }
 
 void
        return (error);
 }
 
 void
-ptswake(tp)
-       register struct tty *tp;
-{
-       if (tp->t_state&TS_ASLEEP) {
-               tp->t_state &= ~TS_ASLEEP;
-               wakeup((caddr_t)&tp->t_outq);
-       }
-       if (tp->t_wsel) {
-               selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
-               tp->t_wsel = 0;
-               tp->t_state &= ~TS_WCOLL;
-       }
-}
-
 ptsstop(tp, flush)
        register struct tty *tp;
        int flush;
 ptsstop(tp, flush)
        register struct tty *tp;
        int flush;
@@ -435,7 +421,6 @@ ptcselect(dev, rw, p)
        case 0:                                 /* exceptional */
                if ((tp->t_state&TS_ISOPEN) &&
                    (pti->pt_flags&PF_PKT && pti->pt_send ||
        case 0:                                 /* exceptional */
                if ((tp->t_state&TS_ISOPEN) &&
                    (pti->pt_flags&PF_PKT && pti->pt_send ||
-                    pti->pt_flags&PF_TIOC && pti->pt_ioc.c_cc ||
                     pti->pt_flags&PF_UCNTL && pti->pt_ucntl))
                        return (1);
                selrecord(p, &pti->pt_selr);
                     pti->pt_flags&PF_UCNTL && pti->pt_ucntl))
                        return (1);
                selrecord(p, &pti->pt_selr);
@@ -574,27 +559,20 @@ ptyioctl(dev, cmd, data, flag, p)
                if (*(int *)data) {
                        if (pti->pt_flags & PF_PKT) {
                                pti->pt_send |= TIOCPKT_IOCTL;
                if (*(int *)data) {
                        if (pti->pt_flags & PF_PKT) {
                                pti->pt_send |= TIOCPKT_IOCTL;
-                               ptcwakeup(tp);
+                               ptcwakeup(tp, FREAD);
                        }
                        tp->t_lflag |= EXTPROC;
                } else {
                        if ((tp->t_state & EXTPROC) &&
                            (pti->pt_flags & PF_PKT)) {
                                pti->pt_send |= TIOCPKT_IOCTL;
                        }
                        tp->t_lflag |= EXTPROC;
                } else {
                        if ((tp->t_state & EXTPROC) &&
                            (pti->pt_flags & PF_PKT)) {
                                pti->pt_send |= TIOCPKT_IOCTL;
-                               ptcwakeup(tp);
+                               ptcwakeup(tp, FREAD);
                        }
                        tp->t_lflag &= ~EXTPROC;
                }
                return(0);
        } else
                        }
                        tp->t_lflag &= ~EXTPROC;
                }
                return(0);
        } else
-       if (cdevsw[major(dev)].d_open == ptcopen) {
-               if ((cmd & 0xffff) == (TIOCIOANS(0) & 0xffff)) {
-                       if (!(pti->pt_flags & PF_LIOC) || pti->pt_ioc.c_cc)
-                               return (EINVAL);
-                       (void) b_to_q(data, IOCPARM_LEN(cmd), &pti->pt_ioc);
-                       wakeup((caddr_t)&pti->pt_ioc);
-                       return (0);
-               }
+       if (cdevsw[major(dev)].d_open == ptcopen)
                switch (cmd) {
 
                case TIOCGPGRP:
                switch (cmd) {
 
                case TIOCGPGRP:
@@ -623,30 +601,6 @@ ptyioctl(dev, cmd, data, flag, p)
                                pti->pt_flags &= ~PF_UCNTL;
                        return (0);
 
                                pti->pt_flags &= ~PF_UCNTL;
                        return (0);
 
-               case TIOCTIOC:
-                       if (*(int *)data) {
-                               if (pti->pt_flags & PF_UCNTL)
-                                       return (EINVAL);
-                               pti->pt_flags |= PF_TIOC;
-                       } else {
-                               pti->pt_flags &= ~(PF_TIOC|PF_LIOC|PF_WIOC);
-                               while (pti->pt_ioc.c_cc)
-                                       (void) getc(&pti->pt_ioc);
-                               wakeup((caddr_t)&pti->pt_ioc);
-                       }
-                       return (0);
-
-               case TIOCBLK:
-                       if (*(int *)data)
-                               pti->pt_flags |= PF_BLOCK;
-                       else {
-                               if (pti->pt_flags & PF_OWAIT)
-                                       wakeup((caddr_t)pti + 1);
-                               pti->pt_flags &= ~(PF_BLOCK|PF_OWAIT);
-                               ptswake(tp);
-                       }
-                       return (0);
-
                case TIOCREMOTE:
                        if (*(int *)data)
                                pti->pt_flags |= PF_REMOTE;
                case TIOCREMOTE:
                        if (*(int *)data)
                                pti->pt_flags |= PF_REMOTE;
@@ -656,10 +610,6 @@ ptyioctl(dev, cmd, data, flag, p)
                        return (0);
 
 #ifdef COMPAT_43
                        return (0);
 
 #ifdef COMPAT_43
-               case FIONREAD:
-                       *(int *)data = tp->t_outq.c_cc;
-                       return (0);
-
                case TIOCSETP:          
                case TIOCSETN:
 #endif
                case TIOCSETP:          
                case TIOCSETN:
 #endif
@@ -681,73 +631,9 @@ ptyioctl(dev, cmd, data, flag, p)
                                ttyinfo(tp);
                        return(0);
                }
                                ttyinfo(tp);
                        return(0);
                }
-       } else if (pti->pt_flags & PF_TIOC) {
-               while (pti->pt_flags & PF_LIOC) {
-                       pti->pt_flags |= PF_WIOC;
-                       switch (tsleep((caddr_t)&pti->pt_flags,TTIPRI-1,5*hz)) {
-                       case TS_OK:
-                               continue;
-                       case TS_SIG:
-                       case TS_TIME:
-                               return (EBUSY);
-                       }
-               }
-               pti->pt_flags |= PF_LIOC | PF_BLOCK;
-               while (pti->pt_ioc.c_cc)
-                       (void) getc(&pti->pt_ioc);
-               (void) b_to_q(&cmd, sizeof cmd, &pti->pt_ioc);
-               if (cmd & IOC_IN)
-                       (void) b_to_q(data, IOCPARM_LEN(cmd), &pti->pt_ioc);
-               ptcwakeup(tp, FREAD);
-               switch (tsleep((caddr_t)&pti->pt_ioc, TTIPRI-1, 5*hz)) {
-               case TS_SIG:
-               case TS_TIME:
-                       while (pti->pt_ioc.c_cc)
-                               (void) getc(&pti->pt_ioc);
-                       if (pti->pt_flags & PF_WIOC)
-                               wakeup((caddr_t)&pti->pt_flags);
-                       if (pti->pt_flags & PF_OWAIT)
-                               wakeup((caddr_t)pti + 1);
-                       pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
-                       ptswake(tp);
-                       return (EBUSY);
-               case TS_OK:
-                       break;
-               }
-               if (pti->pt_ioc.c_cc == 0) {
-                       if (pti->pt_flags & PF_WIOC)
-                               wakeup((caddr_t)&pti->pt_flags);
-                       if (pti->pt_flags & PF_OWAIT)
-                               wakeup((caddr_t)pti + 1);
-                       pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
-                       ptswake(tp);
-                       goto doioctl;
-               }
-               if (q_to_b(&pti->pt_ioc, &error, sizeof error) != sizeof error)
-                       error = EINVAL;
-               if (error == 0 && cmd & IOC_OUT) {
-                       if (IOCPARM_LEN(cmd) != pti->pt_ioc.c_cc)
-                               error = EINVAL;
-                       else
-                               (void) q_to_b(&pti->pt_ioc, data,
-                                   pti->pt_ioc.c_cc);
-               }
-               while (pti->pt_ioc.c_cc)
-                       (void) getc(&pti->pt_ioc);
-               if (pti->pt_flags & PF_WIOC)
-                       wakeup((caddr_t)&pti->pt_flags);
-               if (pti->pt_flags & PF_OWAIT)
-                       wakeup((caddr_t)pti + 1);
-               pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
-               ptswake(tp);
-               return (error);
-       }
-
- doioctl:
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        if (error < 0)
                 error = ttioctl(tp, cmd, data, flag);
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        if (error < 0)
                 error = ttioctl(tp, cmd, data, flag);
-
        if (error < 0) {
                if (pti->pt_flags & PF_UCNTL &&
                    (cmd & ~0xff) == UIOCCMD(0)) {
        if (error < 0) {
                if (pti->pt_flags & PF_UCNTL &&
                    (cmd & ~0xff) == UIOCCMD(0)) {
@@ -779,6 +665,7 @@ ptyioctl(dev, cmd, data, flag, p)
                case TIOCLSET:
 #endif
                        pti->pt_send |= TIOCPKT_IOCTL;
                case TIOCLSET:
 #endif
                        pti->pt_send |= TIOCPKT_IOCTL;
+                       ptcwakeup(tp, FREAD);
                default:
                        break;
                }
                default:
                        break;
                }