typo
[unix-history] / usr / src / sys / kern / tty_subr.c
index 412bcb9..44d708a 100644 (file)
@@ -1,11 +1,17 @@
-/*     tty_subr.c      4.9     %G%     */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)tty_subr.c  7.3 (Berkeley) %G%
+ */
 
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/conf.h"
-#include "../h/buf.h"
-#include "../h/tty.h"
-#include "../h/clist.h"
+#include "param.h"
+#include "systm.h"
+#include "buf.h"
+#include "ioctl.h"
+#include "tty.h"
+#include "clist.h"
 
 char   cwaiting;
 
 
 char   cwaiting;
 
@@ -13,12 +19,12 @@ char        cwaiting;
  * Character list get/put
  */
 getc(p)
  * Character list get/put
  */
 getc(p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register int c, s;
 
 {
        register struct cblock *bp;
        register int c, s;
 
-       s = spl6();
+       s = spltty();
        if (p->c_cc <= 0) {
                c = -1;
                p->c_cc = 0;
        if (p->c_cc <= 0) {
                c = -1;
                p->c_cc = 0;
@@ -27,7 +33,7 @@ register struct clist *p;
                c = *p->c_cf++ & 0377;
                if (--p->c_cc<=0) {
                        bp = (struct cblock *)(p->c_cf-1);
                c = *p->c_cf++ & 0377;
                if (--p->c_cc<=0) {
                        bp = (struct cblock *)(p->c_cf-1);
-                       bp = (struct cblock *) ((int)bp & ~CROUND);
+                       bp = (struct cblock *)((int)bp & ~CROUND);
                        p->c_cf = NULL;
                        p->c_cl = NULL;
                        bp->c_next = cfreelist;
                        p->c_cf = NULL;
                        p->c_cl = NULL;
                        bp->c_next = cfreelist;
@@ -51,7 +57,7 @@ register struct clist *p;
                }
        }
        splx(s);
                }
        }
        splx(s);
-       return(c);
+       return (c);
 }
 
 /*
 }
 
 /*
@@ -59,29 +65,36 @@ register struct clist *p;
  * return number of bytes moved.
  */
 q_to_b(q, cp, cc)
  * return number of bytes moved.
  */
 q_to_b(q, cp, cc)
-register struct clist *q;
-register char *cp;
+       register struct clist *q;
+       register char *cp;
 {
        register struct cblock *bp;
        register int s;
 {
        register struct cblock *bp;
        register int s;
+       register nc;
        char *acp;
 
        if (cc <= 0)
        char *acp;
 
        if (cc <= 0)
-               return(0);
-       s = spl6();
+               return (0);
+       s = spltty();
        if (q->c_cc <= 0) {
                q->c_cc = 0;
                q->c_cf = q->c_cl = NULL;
                splx(s);
        if (q->c_cc <= 0) {
                q->c_cc = 0;
                q->c_cf = q->c_cl = NULL;
                splx(s);
-               return(0);
+               return (0);
        }
        acp = cp;
        }
        acp = cp;
-       cc++;
 
 
-       while (--cc) {
-               *cp++ = *q->c_cf++;
-               if (--q->c_cc <= 0) {
-                       bp = (struct cblock *)(q->c_cf-1);
+       while (cc) {
+               nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
+               nc = MIN(nc, cc);
+               nc = MIN(nc, q->c_cc);
+               (void) bcopy(q->c_cf, cp, (unsigned)nc);
+               q->c_cf += nc;
+               q->c_cc -= nc;
+               cc -= nc;
+               cp += nc;
+               if (q->c_cc <= 0) {
+                       bp = (struct cblock *)(q->c_cf - 1);
                        bp = (struct cblock *)((int)bp & ~CROUND);
                        q->c_cf = q->c_cl = NULL;
                        bp->c_next = cfreelist;
                        bp = (struct cblock *)((int)bp & ~CROUND);
                        q->c_cf = q->c_cl = NULL;
                        bp->c_next = cfreelist;
@@ -107,7 +120,7 @@ register char *cp;
                }
        }
        splx(s);
                }
        }
        splx(s);
-       return(cp-acp);
+       return (cp-acp);
 }
 
 /*
 }
 
 /*
@@ -116,12 +129,12 @@ register char *cp;
  * Stop counting if flag&character is non-null.
  */
 ndqb(q, flag)
  * Stop counting if flag&character is non-null.
  */
 ndqb(q, flag)
-register struct clist *q;
+       register struct clist *q;
 {
 {
-register cc;
-int s;
+       register cc;
+       int s;
 
 
-       s = spl6();
+       s = spltty();
        if (q->c_cc <= 0) {
                cc = -q->c_cc;
                goto out;
        if (q->c_cc <= 0) {
                cc = -q->c_cc;
                goto out;
@@ -147,31 +160,23 @@ int s;
        }
 out:
        splx(s);
        }
 out:
        splx(s);
-       return(cc);
+       return (cc);
 }
 
 }
 
-
-
 /*
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
 /*
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
-register struct clist *q;
-register cc;
+       register struct clist *q;
+       register cc;
 {
 {
-register struct cblock *bp;
-char *end;
-int rem;
-register s;
+       register struct cblock *bp;
+       char *end;
+       int rem, s;
 
 
-       s = spl6();
-       if (q->c_cc < 0) {
-               printf("neg q flush\n");
-               goto out;
-       }
-       if (q->c_cc == 0) {
+       s = spltty();
+       if (q->c_cc <= 0)
                goto out;
                goto out;
-       }
        while (cc>0 && q->c_cc) {
                bp = (struct cblock *)((int)q->c_cf & ~CROUND);
                if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
        while (cc>0 && q->c_cc) {
                bp = (struct cblock *)((int)q->c_cf & ~CROUND);
                if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
@@ -216,17 +221,17 @@ out:
 
 
 putc(c, p)
 
 
 putc(c, p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register char *cp;
        register s;
 
 {
        register struct cblock *bp;
        register char *cp;
        register s;
 
-       s = spl6();
+       s = spltty();
        if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
                if ((bp = cfreelist) == NULL) {
                        splx(s);
        if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
                if ((bp = cfreelist) == NULL) {
                        splx(s);
-                       return(-1);
+                       return (-1);
                }
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
                }
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
@@ -236,7 +241,7 @@ register struct clist *p;
                bp = (struct cblock *)cp - 1;
                if ((bp->c_next = cfreelist) == NULL) {
                        splx(s);
                bp = (struct cblock *)cp - 1;
                if ((bp->c_next = cfreelist) == NULL) {
                        splx(s);
-                       return(-1);
+                       return (-1);
                }
                bp = bp->c_next;
                cfreelist = bp->c_next;
                }
                bp = bp->c_next;
                cfreelist = bp->c_next;
@@ -248,30 +253,27 @@ register struct clist *p;
        p->c_cc++;
        p->c_cl = cp;
        splx(s);
        p->c_cc++;
        p->c_cl = cp;
        splx(s);
-       return(0);
+       return (0);
 }
 
 }
 
-
-
 /*
  * copy buffer to clist.
  * return number of bytes not transfered.
  */
 b_to_q(cp, cc, q)
 /*
  * copy buffer to clist.
  * return number of bytes not transfered.
  */
 b_to_q(cp, cc, q)
-register char *cp;
-struct clist *q;
-register int cc;
+       register char *cp;
+       struct clist *q;
+       register int cc;
 {
        register char *cq;
        register struct cblock *bp;
 {
        register char *cq;
        register struct cblock *bp;
-       register s, acc;
+       register s, nc;
+       int acc;
 
        if (cc <= 0)
 
        if (cc <= 0)
-               return(0);
+               return (0);
        acc = cc;
        acc = cc;
-
-
-       s = spl6();
+       s = spltty();
        if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
                if ((bp = cfreelist) == NULL) 
                        goto out;
        if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
                if ((bp = cfreelist) == NULL) 
                        goto out;
@@ -283,7 +285,7 @@ register int cc;
 
        while (cc) {
                if (((int)cq & CROUND) == 0) {
 
        while (cc) {
                if (((int)cq & CROUND) == 0) {
-                       bp = (struct cblock *) cq - 1;
+                       bp = (struct cblock *)cq - 1;
                        if ((bp->c_next = cfreelist) == NULL) 
                                goto out;
                        bp = bp->c_next;
                        if ((bp->c_next = cfreelist) == NULL) 
                                goto out;
                        bp = bp->c_next;
@@ -292,14 +294,17 @@ register int cc;
                        bp->c_next = NULL;
                        cq = bp->c_info;
                }
                        bp->c_next = NULL;
                        cq = bp->c_info;
                }
-               *cq++ = *cp++;
-               cc--;
+               nc = MIN(cc, sizeof (struct cblock) - ((int)cq & CROUND));
+               (void) bcopy(cp, cq, (unsigned)nc);
+               cp += nc;
+               cq += nc;
+               cc -= nc;
        }
 out:
        q->c_cl = cq;
        }
 out:
        q->c_cl = cq;
-       q->c_cc += acc-cc;
+       q->c_cc += acc - cc;
        splx(s);
        splx(s);
-       return(cc);
+       return (cc);
 }
 
 /*
 }
 
 /*
@@ -312,8 +317,8 @@ out:
  */
 char *
 nextc(p, cp)
  */
 char *
 nextc(p, cp)
-register struct clist *p;
-register char *cp;
+       register struct clist *p;
+       register char *cp;
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
@@ -328,13 +333,13 @@ register char *cp;
  * Remove the last character in the list and return it.
  */
 unputc(p)
  * Remove the last character in the list and return it.
  */
 unputc(p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register int c, s;
        struct cblock *obp;
 
 {
        register struct cblock *bp;
        register int c, s;
        struct cblock *obp;
 
-       s = spl6();
+       s = spltty();
        if (p->c_cc <= 0)
                c = -1;
        else {
        if (p->c_cc <= 0)
                c = -1;
        else {
@@ -368,47 +373,140 @@ register struct clist *p;
 /*
  * Put the chars in the from que
  * on the end of the to que.
 /*
  * Put the chars in the from que
  * on the end of the to que.
- *
- * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
  */
 catq(from, to)
  */
 catq(from, to)
-struct clist *from, *to;
+       struct clist *from, *to;
 {
 {
-       register c;
-
-       while ((c = getc(from)) >= 0)
-               (void) putc(c, to);
+       char bbuf[CBSIZE*4];
+       register s, c;
+
+       s = spltty();
+       if (to->c_cc == 0) {
+               *to = *from;
+               from->c_cc = 0;
+               from->c_cf = NULL;
+               from->c_cl = NULL;
+               splx(s);
+               return;
+       }
+       splx(s);
+       while (from->c_cc > 0) {
+               c = q_to_b(from, bbuf, sizeof bbuf);
+               (void) b_to_q(bbuf, c, to);
+       }
 }
 
 }
 
+#ifdef unneeded
 /*
 /*
- * integer (2-byte) get/put
- * using clists
+ * Integer (short) get/put using clists.
  */
  */
-#ifdef unneeded
+typedef        u_short word_t;
+
 getw(p)
 getw(p)
-register struct clist *p;
+       register struct clist *p;
 {
 {
-       register int s;
+       register int s, c;
+       register struct cblock *bp;
 
        if (p->c_cc <= 1)
                return(-1);
 
        if (p->c_cc <= 1)
                return(-1);
-       s = getc(p);
-       return(s | (getc(p)<<8));
-}
+       if (p->c_cc & 01) {
+               c = getc(p);
+#if BYTE_ORDER == LITTLE_ENDIAN
+               return (c | (getc(p)<<8));
+#else
+               return (getc(p) | (c<<8));
+#endif
+       }
+       s = spltty();
+#if BYTE_ORDER == LITTLE_ENDIAN
+       c = (((u_char *)p->c_cf)[0] << 8) | ((u_char *)p->c_cf)[1];
+#else
+       c = (((u_char *)p->c_cf)[1] << 8) | ((u_char *)p->c_cf)[0];
 #endif
 #endif
+       p->c_cf += sizeof (word_t);
+       p->c_cc -= sizeof (word_t);
+       if (p->c_cc <= 0) {
+               bp = (struct cblock *)(p->c_cf-1);
+               bp = (struct cblock *)((int)bp & ~CROUND);
+               p->c_cf = NULL;
+               p->c_cl = NULL;
+               bp->c_next = cfreelist;
+               cfreelist = bp;
+               cfreecount += CBSIZE;
+               if (cwaiting) {
+                       wakeup(&cwaiting);
+                       cwaiting = 0;
+               }
+       } else if (((int)p->c_cf & CROUND) == 0) {
+               bp = (struct cblock *)(p->c_cf);
+               bp--;
+               p->c_cf = bp->c_next->c_info;
+               bp->c_next = cfreelist;
+               cfreelist = bp;
+               cfreecount += CBSIZE;
+               if (cwaiting) {
+                       wakeup(&cwaiting);
+                       cwaiting = 0;
+               }
+       }
+       splx(s);
+       return (c);
+}
 
 putw(c, p)
 
 putw(c, p)
-register struct clist *p;
+       register struct clist *p;
+       word_t c;
 {
        register s;
 {
        register s;
+       register struct cblock *bp;
+       register char *cp;
 
 
-       s = spl6();
+       s = spltty();
        if (cfreelist==NULL) {
                splx(s);
                return(-1);
        }
        if (cfreelist==NULL) {
                splx(s);
                return(-1);
        }
-       (void) putc(c, p);
-       (void) putc(c>>8, p);
+       if (p->c_cc & 01) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+               (void) putc(c, p);
+               (void) putc(c>>8, p);
+#else
+               (void) putc(c>>8, p);
+               (void) putc(c, p);
+#endif
+       } else {
+               if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
+                       if ((bp = cfreelist) == NULL) {
+                               splx(s);
+                               return (-1);
+                       }
+                       cfreelist = bp->c_next;
+                       cfreecount -= CBSIZE;
+                       bp->c_next = NULL;
+                       p->c_cf = cp = bp->c_info;
+               } else if (((int)cp & CROUND) == 0) {
+                       bp = (struct cblock *)cp - 1;
+                       if ((bp->c_next = cfreelist) == NULL) {
+                               splx(s);
+                               return (-1);
+                       }
+                       bp = bp->c_next;
+                       cfreelist = bp->c_next;
+                       cfreecount -= CBSIZE;
+                       bp->c_next = NULL;
+                       cp = bp->c_info;
+               }
+#if defined(vax)
+               *(word_t *)cp = c;
+#else
+               ((u_char *)cp)[0] = c>>8;
+               ((u_char *)cp)[1] = c;
+#endif
+               p->c_cl = cp + sizeof (word_t);
+               p->c_cc += sizeof (word_t);
+       }
        splx(s);
        splx(s);
-       return(0);
+       return (0);
 }
 }
+#endif unneeded