BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / sys / tty.c
index 914ca5c..abe68b9 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)tty.c       7.1 (Berkeley) 6/5/86
+ *     @(#)tty.c       7.12 (Berkeley) 5/26/88
  */
 
 #include "../machine/reg.h"
  */
 
 #include "../machine/reg.h"
 #include "ioctl.h"
 #include "tty.h"
 #include "proc.h"
 #include "ioctl.h"
 #include "tty.h"
 #include "proc.h"
-#include "inode.h"
 #include "file.h"
 #include "conf.h"
 #include "file.h"
 #include "conf.h"
-#include "buf.h"
-#include "dk.h"
+#include "dkstat.h"
 #include "uio.h"
 #include "kernel.h"
 
 #include "uio.h"
 #include "kernel.h"
 
@@ -108,6 +106,8 @@ struct      ttychars ttydefaults = {
        CBRK,   CSUSP,  CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT
 };
 
        CBRK,   CSUSP,  CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT
 };
 
+extern struct tty *constty;            /* temporary virtual console */
+
 ttychars(tp)
        struct tty *tp;
 {
 ttychars(tp)
        struct tty *tp;
 {
@@ -132,7 +132,7 @@ ttywait(tp)
        register int s = spltty();
 
        while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
        register int s = spltty();
 
        while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
-           tp->t_state&TS_CARR_ON) {
+           tp->t_state&TS_CARR_ON && tp->t_oproc) {
                (*tp->t_oproc)(tp);
                tp->t_state |= TS_ASLEEP;
                sleep((caddr_t)&tp->t_outq, TTOPRI);
                (*tp->t_oproc)(tp);
                tp->t_state |= TS_ASLEEP;
                sleep((caddr_t)&tp->t_outq, TTOPRI);
@@ -222,13 +222,9 @@ ttrstrt(tp)
 ttstart(tp)
        register struct tty *tp;
 {
 ttstart(tp)
        register struct tty *tp;
 {
-       register s;
 
 
-       s = spltty();
-       if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
-           tp->t_oproc)                /* kludge for pty */
+       if (tp->t_oproc)                /* kludge for pty */
                (*tp->t_oproc)(tp);
                (*tp->t_oproc)(tp);
-       splx(s);
 }
 
 /*
 }
 
 /*
@@ -244,6 +240,7 @@ ttioctl(tp, com, data, flag)
        int s;
        register int newflags;
 
        int s;
        register int newflags;
 
+
        /*
         * If the ioctl involves modification,
         * hang if in the background.
        /*
         * If the ioctl involves modification,
         * hang if in the background.
@@ -465,7 +462,7 @@ ttioctl(tp, com, data, flag)
                break;
 
        case TIOCLGET:
                break;
 
        case TIOCLGET:
-               *(int *)data = ((unsigned) tp->t_flags) >> 16;
+               *(int *)data = ((unsigned)tp->t_flags) >> 16;
                break;
 
        /*
                break;
 
        /*
@@ -504,6 +501,19 @@ ttioctl(tp, com, data, flag)
                *(struct winsize *)data = tp->t_winsize;
                break;
 
                *(struct winsize *)data = tp->t_winsize;
                break;
 
+       case TIOCCONS:
+               if (*(int *)data) {
+                       if (constty != NULL)
+                               return (EBUSY);
+#ifndef        UCONSOLE
+                       if (!suser())
+                               return (EPERM);
+#endif
+                       constty = tp;
+               } else if (tp == constty)
+                       constty = NULL;
+               break;
+
        default:
                return (-1);
        }
        default:
                return (-1);
        }
@@ -535,7 +545,7 @@ ttselect(dev, rw)
 
        case FREAD:
                nread = ttnread(tp);
 
        case FREAD:
                nread = ttnread(tp);
-               if ((nread > 0) || ((tp->t_state & TS_CARR_ON) == 0))
+               if (nread > 0 || (tp->t_state & TS_CARR_ON) == 0)
                        goto win;
                if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
                        tp->t_state |= TS_RCOLL;
                        goto win;
                if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
                        tp->t_state |= TS_RCOLL;
@@ -607,6 +617,8 @@ ttyclose(tp)
        register struct tty *tp;
 {
 
        register struct tty *tp;
 {
 
+       if (constty == tp)
+               constty = NULL;
        ttyflush(tp, FREAD|FWRITE);
        tp->t_pgrp = 0;
        tp->t_state = 0;
        ttyflush(tp, FREAD|FWRITE);
        tp->t_pgrp = 0;
        tp->t_state = 0;
@@ -831,7 +843,7 @@ ttyinput(c, tp)
                if (tp->t_rawq.c_cc > TTYHOG) {
                        if (tp->t_outq.c_cc < TTHIWAT(tp) &&
                            tp->t_line == NTTYDISC)
                if (tp->t_rawq.c_cc > TTYHOG) {
                        if (tp->t_outq.c_cc < TTHIWAT(tp) &&
                            tp->t_line == NTTYDISC)
-                               (void) ttyoutput(CTRL(g), tp);
+                               (void) ttyoutput(CTRL('g'), tp);
                } else if (putc(c, &tp->t_rawq) >= 0) {
                        ttwakeup(tp);
                        ttyecho(c, tp);
                } else if (putc(c, &tp->t_rawq) >= 0) {
                        ttwakeup(tp);
                        ttyecho(c, tp);
@@ -905,7 +917,7 @@ ttyinput(c, tp)
         */
        if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
                if (tp->t_line == NTTYDISC)
         */
        if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
                if (tp->t_line == NTTYDISC)
-                       (void) ttyoutput(CTRL(g), tp);
+                       (void) ttyoutput(CTRL('g'), tp);
                goto endcase;
        }
 
                goto endcase;
        }
 
@@ -1256,25 +1268,29 @@ checktandem:
  * (from uprintf/tprintf).  Allow some space over the normal
  * hiwater mark so we don't lose messages due to normal flow
  * control, but don't let the tty run amok.
  * (from uprintf/tprintf).  Allow some space over the normal
  * hiwater mark so we don't lose messages due to normal flow
  * control, but don't let the tty run amok.
+ * Sleeps here are not interruptible, but we return prematurely
+ * if new signals come in.
  */
 ttycheckoutq(tp, wait)
        register struct tty *tp;
        int wait;
 {
  */
 ttycheckoutq(tp, wait)
        register struct tty *tp;
        int wait;
 {
-       int hiwat, s;
+       int hiwat, s, oldsig;
 
        hiwat = TTHIWAT(tp);
        s = spltty();
 
        hiwat = TTHIWAT(tp);
        s = spltty();
+       oldsig = u.u_procp->p_sig;
        if (tp->t_outq.c_cc > hiwat + 200)
        if (tp->t_outq.c_cc > hiwat + 200)
-           while (tp->t_outq.c_cc > hiwat) {
-               ttstart(tp);
-               if (wait == 0) {
-                       splx(s);
-                       return (0);
+               while (tp->t_outq.c_cc > hiwat) {
+                       ttstart(tp);
+                       if (wait == 0 || u.u_procp->p_sig != oldsig) {
+                               splx(s);
+                               return (0);
+                       }
+                       timeout(wakeup, (caddr_t)&tp->t_outq, hz);
+                       tp->t_state |= TS_ASLEEP;
+                       sleep((caddr_t)&tp->t_outq, PZERO - 1);
                }
                }
-               tp->t_state |= TS_ASLEEP;
-               sleep((caddr_t)&tp->t_outq, TTOPRI);
-       }
        splx(s);
        return (1);
 }
        splx(s);
        return (1);
 }
@@ -1318,6 +1334,10 @@ loop:
         * in acquiring new space.
         */
        while (uio->uio_resid > 0) {
         * in acquiring new space.
         */
        while (uio->uio_resid > 0) {
+               if (tp->t_outq.c_cc > hiwat) {
+                       cc = 0;
+                       goto ovhiwat;
+               }
                /*
                 * Grab a hunk of data from the user.
                 */
                /*
                 * Grab a hunk of data from the user.
                 */
@@ -1335,8 +1355,6 @@ loop:
                error = uiomove(cp, cc, UIO_WRITE, uio);
                if (error)
                        break;
                error = uiomove(cp, cc, UIO_WRITE, uio);
                if (error)
                        break;
-               if (tp->t_outq.c_cc > hiwat)
-                       goto ovhiwat;
                if (tp->t_flags&FLUSHO)
                        continue;
                /*
                if (tp->t_flags&FLUSHO)
                        continue;
                /*
@@ -1380,8 +1398,8 @@ loop:
                        if (tp->t_flags & (RAW|LITOUT))
                                ce = cc;
                        else {
                        if (tp->t_flags & (RAW|LITOUT))
                                ce = cc;
                        else {
-                               ce = cc - scanc((unsigned)cc, (caddr_t)cp,
-                                  (caddr_t)partab, 077);
+                               ce = cc - scanc((unsigned)cc, (u_char *)cp,
+                                  (u_char *)partab, 077);
                                /*
                                 * If ce is zero, then we're processing
                                 * a special character through ttyoutput.
                                /*
                                 * If ce is zero, then we're processing
                                 * a special character through ttyoutput.
@@ -1438,22 +1456,22 @@ loop:
        return (error);
 
 ovhiwat:
        return (error);
 
 ovhiwat:
-       s = spltty();
        if (cc != 0) {
                uio->uio_iov->iov_base -= cc;
                uio->uio_iov->iov_len += cc;
                uio->uio_resid += cc;
                uio->uio_offset -= cc;
        }
        if (cc != 0) {
                uio->uio_iov->iov_base -= cc;
                uio->uio_iov->iov_len += cc;
                uio->uio_resid += cc;
                uio->uio_offset -= cc;
        }
+       ttstart(tp);
+       s = spltty();
        /*
        /*
-        * This can only occur if FLUSHO
-        * is also set in t_flags.
+        * This can only occur if FLUSHO is set in t_flags,
+        * or if ttstart/oproc is synchronous (or very fast).
         */
        if (tp->t_outq.c_cc <= hiwat) {
                splx(s);
                goto loop;
        }
         */
        if (tp->t_outq.c_cc <= hiwat) {
                splx(s);
                goto loop;
        }
-       ttstart(tp);
        if (tp->t_state&TS_NBIO) {
                splx(s);
                if (uio->uio_resid == cnt)
        if (tp->t_state&TS_NBIO) {
                splx(s);
                if (uio->uio_resid == cnt)