BSD 4_4 release
[unix-history] / usr / src / sys / kern / tty_subr.c
index 299c90b..1679654 100644 (file)
@@ -1,13 +1,50 @@
-/*     tty_subr.c      6.7     84/12/20        */
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This module is believed to contain source code proprietary to AT&T.
+ * Use and redistribution is subject to the Berkeley Software License
+ * Agreement and your Software Agreement with AT&T (Western Electric).
+ *
+ *     @(#)tty_subr.c  8.1 (Berkeley) 6/10/93
+ */
 
 
-#include "param.h"
-#include "systm.h"
-#include "conf.h"
-#include "buf.h"
-#include "tty.h"
-#include "clist.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/clist.h>
 
 char   cwaiting;
 
 char   cwaiting;
+struct cblock *cfree, *cfreelist;
+int    cfreecount, nclist;
+
+#define setquote(cp) \
+       setbit(((char *)((int)(cp)&~CROUND)+sizeof(struct cblock *)), \
+               (int)(cp)&CROUND)
+#define isquote(cp) \
+       isset(((char *)((int)(cp)&~CROUND)+sizeof(struct cblock *)), \
+               (int)(cp)&CROUND)
+#define cbptr(x) ((struct cblock *)(x))
+
+/*
+ * Initialize clist by freeing all character blocks.
+ */
+cinit()
+{
+       register int ccp;
+       register struct cblock *cp;
+
+       ccp = (int) cfree;
+       ccp = (ccp + CROUND) & ~CROUND;
+       for(cp = (struct cblock *) ccp; cp < &cfree[nclist - 1]; cp++) {
+               cp->c_next = cfreelist;
+               cfreelist = cp;
+               cfreecount += CBSIZE;
+       }
+}
 
 /*
  * Character list get/put
 
 /*
  * Character list get/put
@@ -24,10 +61,13 @@ getc(p)
                p->c_cc = 0;
                p->c_cf = p->c_cl = NULL;
        } else {
                p->c_cc = 0;
                p->c_cf = p->c_cl = NULL;
        } else {
-               c = *p->c_cf++ & 0377;
+               c = *p->c_cf & 0377;
+               if (isquote(p->c_cf))
+                       c |= TTY_QUOTE;
+               p->c_cf++;
                if (--p->c_cc<=0) {
                if (--p->c_cc<=0) {
-                       bp = (struct cblock *)(p->c_cf-1);
-                       bp = (struct cblock *) ((int)bp & ~CROUND);
+                       bp = cbptr(p->c_cf-1);
+                       bp = cbptr((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;
@@ -38,7 +78,7 @@ getc(p)
                                cwaiting = 0;
                        }
                } else if (((int)p->c_cf & CROUND) == 0){
                                cwaiting = 0;
                        }
                } else if (((int)p->c_cf & CROUND) == 0){
-                       bp = (struct cblock *)(p->c_cf);
+                       bp = cbptr(p->c_cf);
                        bp--;
                        p->c_cf = bp->c_next->c_info;
                        bp->c_next = cfreelist;
                        bp--;
                        p->c_cf = bp->c_next->c_info;
                        bp->c_next = cfreelist;
@@ -51,7 +91,7 @@ getc(p)
                }
        }
        splx(s);
                }
        }
        splx(s);
-       return(c);
+       return (c);
 }
 
 /*
 }
 
 /*
@@ -61,35 +101,35 @@ getc(p)
 q_to_b(q, cp, cc)
        register struct clist *q;
        register char *cp;
 q_to_b(q, cp, cc)
        register struct clist *q;
        register char *cp;
+       int cc;
 {
        register struct cblock *bp;
 {
        register struct cblock *bp;
-       register int s;
-       register nc;
+       register int s, nc;
        char *acp;
 
        if (cc <= 0)
        char *acp;
 
        if (cc <= 0)
-               return(0);
+               return (0);
        s = spltty();
        if (q->c_cc <= 0) {
                q->c_cc = 0;
                q->c_cf = q->c_cl = NULL;
                splx(s);
        s = spltty();
        if (q->c_cc <= 0) {
                q->c_cc = 0;
                q->c_cf = q->c_cl = NULL;
                splx(s);
-               return(0);
+               return (0);
        }
        acp = cp;
 
        while (cc) {
        }
        acp = cp;
 
        while (cc) {
-               nc = sizeof(struct cblock) - ((int)q->c_cf & CROUND);
-               nc = MIN(nc, cc);
-               nc = MIN(nc, q->c_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) {
                (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);
+                       bp = cbptr(q->c_cf - 1);
+                       bp = cbptr((int)bp & ~CROUND);
                        q->c_cf = q->c_cl = NULL;
                        bp->c_next = cfreelist;
                        cfreelist = bp;
                        q->c_cf = q->c_cl = NULL;
                        bp->c_next = cfreelist;
                        cfreelist = bp;
@@ -101,7 +141,7 @@ q_to_b(q, cp, cc)
                        break;
                }
                if (((int)q->c_cf & CROUND) == 0) {
                        break;
                }
                if (((int)q->c_cf & CROUND) == 0) {
-                       bp = (struct cblock *)(q->c_cf);
+                       bp = cbptr(q->c_cf);
                        bp--;
                        q->c_cf = bp->c_next->c_info;
                        bp->c_next = cfreelist;
                        bp--;
                        q->c_cf = bp->c_next->c_info;
                        bp->c_next = cfreelist;
@@ -114,7 +154,7 @@ q_to_b(q, cp, cc)
                }
        }
        splx(s);
                }
        }
        splx(s);
-       return(cp-acp);
+       return (cp-acp);
 }
 
 /*
 }
 
 /*
@@ -124,9 +164,9 @@ q_to_b(q, cp, cc)
  */
 ndqb(q, flag)
        register struct clist *q;
  */
 ndqb(q, flag)
        register struct clist *q;
+       int flag;
 {
 {
-       register cc;
-       int s;
+       register int cc, s;
 
        s = spltty();
        if (q->c_cc <= 0) {
 
        s = spltty();
        if (q->c_cc <= 0) {
@@ -154,28 +194,25 @@ ndqb(q, flag)
        }
 out:
        splx(s);
        }
 out:
        splx(s);
-       return(cc);
+       return (cc);
 }
 
 }
 
-
-
 /*
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
        register struct clist *q;
 /*
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
        register struct clist *q;
-       register cc;
+       register int cc;
 {
        register struct cblock *bp;
        char *end;
        int rem, s;
 
        s = spltty();
 {
        register struct cblock *bp;
        char *end;
        int rem, s;
 
        s = spltty();
-       if (q->c_cc <= 0) {
+       if (q->c_cc <= 0)
                goto out;
                goto out;
-       }
        while (cc>0 && q->c_cc) {
        while (cc>0 && q->c_cc) {
-               bp = (struct cblock *)((int)q->c_cf & ~CROUND);
+               bp = cbptr((int)q->c_cf & ~CROUND);
                if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
                        end = q->c_cl;
                } else {
                if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
                        end = q->c_cl;
                } else {
@@ -218,27 +255,29 @@ out:
 
 
 putc(c, p)
 
 
 putc(c, p)
+       int c;
        register struct clist *p;
 {
        register struct cblock *bp;
        register char *cp;
        register struct clist *p;
 {
        register struct cblock *bp;
        register char *cp;
-       register s;
+       register int s;
 
        s = spltty();
 
        s = spltty();
-       if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
+       if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {   /* no cblocks yet */
                if ((bp = cfreelist) == NULL) {
                        splx(s);
                if ((bp = cfreelist) == NULL) {
                        splx(s);
-                       return(-1);
+                       return (-1);
                }
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
                bp->c_next = NULL;
                }
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
                bp->c_next = NULL;
+               bzero(bp->c_quote, CBQSIZE);
                p->c_cf = cp = bp->c_info;
        } else if (((int)cp & CROUND) == 0) {
                p->c_cf = cp = bp->c_info;
        } else if (((int)cp & CROUND) == 0) {
-               bp = (struct cblock *)cp - 1;
+               bp = cbptr(cp) - 1;     /* pointer arith */
                if ((bp->c_next = cfreelist) == NULL) {
                        splx(s);
                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;
@@ -246,15 +285,15 @@ putc(c, p)
                bp->c_next = NULL;
                cp = bp->c_info;
        }
                bp->c_next = NULL;
                cp = bp->c_info;
        }
+       if (c&TTY_QUOTE)
+               setquote(cp);
        *cp++ = c;
        p->c_cc++;
        p->c_cl = cp;
        splx(s);
        *cp++ = c;
        p->c_cc++;
        p->c_cl = cp;
        splx(s);
-       return(0);
+       return (0);
 }
 
 }
 
-
-
 /*
  * copy buffer to clist.
  * return number of bytes not transfered.
 /*
  * copy buffer to clist.
  * return number of bytes not transfered.
@@ -266,11 +305,11 @@ b_to_q(cp, cc, q)
 {
        register char *cq;
        register struct cblock *bp;
 {
        register char *cq;
        register struct cblock *bp;
-       register s, nc;
+       register int s, nc;
        int acc;
 
        if (cc <= 0)
        int acc;
 
        if (cc <= 0)
-               return(0);
+               return (0);
        acc = cc;
        s = spltty();
        if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
        acc = cc;
        s = spltty();
        if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
@@ -278,22 +317,24 @@ b_to_q(cp, cc, q)
                        goto out;
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
                        goto out;
                cfreelist = bp->c_next;
                cfreecount -= CBSIZE;
+               bzero(bp->c_quote, CBQSIZE);
                bp->c_next = NULL;
                q->c_cf = cq = bp->c_info;
        }
 
        while (cc) {
                if (((int)cq & CROUND) == 0) {
                bp->c_next = NULL;
                q->c_cf = cq = bp->c_info;
        }
 
        while (cc) {
                if (((int)cq & CROUND) == 0) {
-                       bp = (struct cblock *) cq - 1;
+                       bp = cbptr(cq) - 1;
                        if ((bp->c_next = cfreelist) == NULL) 
                                goto out;
                        bp = bp->c_next;
                        cfreelist = bp->c_next;
                        cfreecount -= CBSIZE;
                        if ((bp->c_next = cfreelist) == NULL) 
                                goto out;
                        bp = bp->c_next;
                        cfreelist = bp->c_next;
                        cfreecount -= CBSIZE;
+                       bzero(bp->c_quote, CBQSIZE);
                        bp->c_next = NULL;
                        cq = bp->c_info;
                }
                        bp->c_next = NULL;
                        cq = bp->c_info;
                }
-               nc = MIN(cc, sizeof(struct cblock) - ((int)cq & CROUND));
+               nc = min(cc, sizeof (struct cblock) - ((int)cq & CROUND));
                (void) bcopy(cp, cq, (unsigned)nc);
                cp += nc;
                cq += nc;
                (void) bcopy(cp, cq, (unsigned)nc);
                cp += nc;
                cq += nc;
@@ -315,14 +356,19 @@ out:
  * pointer becomes invalid.  Note that interrupts are NOT masked.
  */
 char *
  * pointer becomes invalid.  Note that interrupts are NOT masked.
  */
 char *
-nextc(p, cp)
+nextc(p, cp, c)
        register struct clist *p;
        register char *cp;
        register struct clist *p;
        register char *cp;
+       register int *c;
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
-               if (((int)cp & CROUND) == 0)
-                       return (((struct cblock *)cp)[-1].c_next->c_info);
+               if (((int)cp & CROUND) == 0) {
+                       cp = (cbptr(cp))[-1].c_next->c_info;
+               }
+               *c = *cp;
+               if (isquote(cp))
+                       *c |= TTY_QUOTE;
                return (cp);
        }
        return (0);
                return (cp);
        }
        return (0);
@@ -343,18 +389,21 @@ unputc(p)
                c = -1;
        else {
                c = *--p->c_cl;
                c = -1;
        else {
                c = *--p->c_cl;
+               if (isquote(p->c_cl))
+                       c |= TTY_QUOTE;
                if (--p->c_cc <= 0) {
                if (--p->c_cc <= 0) {
-                       bp = (struct cblock *)p->c_cl;
-                       bp = (struct cblock *)((int)bp & ~CROUND);
+                       bp = cbptr(p->c_cl);
+                       bp = cbptr((int)bp & ~CROUND);
                        p->c_cl = p->c_cf = NULL;
                        bp->c_next = cfreelist;
                        cfreelist = bp;
                        cfreecount += CBSIZE;
                        p->c_cl = p->c_cf = NULL;
                        bp->c_next = cfreelist;
                        cfreelist = bp;
                        cfreecount += CBSIZE;
-               } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
+               } else if (p->c_cl == (cbptr((int)p->c_cl & ~CROUND))->c_info) {
                        p->c_cl = (char *)((int)p->c_cl & ~CROUND);
                        p->c_cl = (char *)((int)p->c_cl & ~CROUND);
-                       bp = (struct cblock *)p->c_cf;
-                       bp = (struct cblock *)((int)bp & ~CROUND);
-                       while (bp->c_next != (struct cblock *)p->c_cl)
+
+                       bp = cbptr(p->c_cf);
+                       bp = cbptr((int)bp & ~CROUND);
+                       while (bp->c_next != cbptr(p->c_cl))
                                bp = bp->c_next;
                        obp = bp;
                        p->c_cl = (char *)(bp + 1);
                                bp = bp->c_next;
                        obp = bp;
                        p->c_cl = (char *)(bp + 1);
@@ -376,8 +425,10 @@ unputc(p)
 catq(from, to)
        struct clist *from, *to;
 {
 catq(from, to)
        struct clist *from, *to;
 {
+#ifdef notdef
        char bbuf[CBSIZE*4];
        char bbuf[CBSIZE*4];
-       register s, c;
+#endif
+       register int s, c;
 
        s = spltty();
        if (to->c_cc == 0) {
 
        s = spltty();
        if (to->c_cc == 0) {
@@ -389,16 +440,20 @@ catq(from, to)
                return;
        }
        splx(s);
                return;
        }
        splx(s);
+#ifdef notdef
        while (from->c_cc > 0) {
                c = q_to_b(from, bbuf, sizeof bbuf);
                (void) b_to_q(bbuf, c, to);
        }
        while (from->c_cc > 0) {
                c = q_to_b(from, bbuf, sizeof bbuf);
                (void) b_to_q(bbuf, c, to);
        }
+#endif
+       /* XXX - FIX */
+       while ((c = getc(from)) >= 0)
+               putc(c, to);
 }
 
 #ifdef unneeded
 /*
 }
 
 #ifdef unneeded
 /*
- * Integer (short) get/put
- * using clists
+ * Integer (short) get/put using clists.
  */
 typedef        u_short word_t;
 
  */
 typedef        u_short word_t;
 
@@ -412,15 +467,23 @@ getw(p)
                return(-1);
        if (p->c_cc & 01) {
                c = getc(p);
                return(-1);
        if (p->c_cc & 01) {
                c = getc(p);
-               return(c | (getc(p)<<8));
+#if BYTE_ORDER == LITTLE_ENDIAN
+               return (c | (getc(p)<<8));
+#else
+               return (getc(p) | (c<<8));
+#endif
        }
        s = spltty();
        }
        s = spltty();
-       c = *((word_t *)p->c_cf);
-       p->c_cf += sizeof(word_t);
-       p->c_cc -= sizeof(word_t);
+#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
+       p->c_cf += sizeof (word_t);
+       p->c_cc -= sizeof (word_t);
        if (p->c_cc <= 0) {
        if (p->c_cc <= 0) {
-               bp = (struct cblock *)(p->c_cf-1);
-               bp = (struct cblock *) ((int)bp & ~CROUND);
+               bp = cbptr(p->c_cf-1);
+               bp = cbptr((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;
@@ -431,7 +494,7 @@ getw(p)
                        cwaiting = 0;
                }
        } else if (((int)p->c_cf & CROUND) == 0) {
                        cwaiting = 0;
                }
        } else if (((int)p->c_cf & CROUND) == 0) {
-               bp = (struct cblock *)(p->c_cf);
+               bp = cbptr(p->c_cf);
                bp--;
                p->c_cf = bp->c_next->c_info;
                bp->c_next = cfreelist;
                bp--;
                p->c_cf = bp->c_next->c_info;
                bp->c_next = cfreelist;
@@ -450,7 +513,7 @@ putw(c, p)
        register struct clist *p;
        word_t c;
 {
        register struct clist *p;
        word_t c;
 {
-       register s;
+       register int s;
        register struct cblock *bp;
        register char *cp;
 
        register struct cblock *bp;
        register char *cp;
 
@@ -460,8 +523,13 @@ putw(c, p)
                return(-1);
        }
        if (p->c_cc & 01) {
                return(-1);
        }
        if (p->c_cc & 01) {
+#if BYTE_ORDER == LITTLE_ENDIAN
                (void) putc(c, p);
                (void) putc(c>>8, p);
                (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) {
        } else {
                if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
                        if ((bp = cfreelist) == NULL) {
@@ -473,7 +541,7 @@ putw(c, p)
                        bp->c_next = NULL;
                        p->c_cf = cp = bp->c_info;
                } else if (((int)cp & CROUND) == 0) {
                        bp->c_next = NULL;
                        p->c_cf = cp = bp->c_info;
                } else if (((int)cp & CROUND) == 0) {
-                       bp = (struct cblock *)cp - 1;
+                       bp = cbptr(cp) - 1;
                        if ((bp->c_next = cfreelist) == NULL) {
                                splx(s);
                                return (-1);
                        if ((bp->c_next = cfreelist) == NULL) {
                                splx(s);
                                return (-1);
@@ -484,11 +552,16 @@ putw(c, p)
                        bp->c_next = NULL;
                        cp = bp->c_info;
                }
                        bp->c_next = NULL;
                        cp = bp->c_info;
                }
+#if defined(vax)
                *(word_t *)cp = c;
                *(word_t *)cp = c;
-               p->c_cl = cp + sizeof(word_t);
-               p->c_cc += sizeof(word_t);
+#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);
        return (0);
 }
        }
        splx(s);
        return (0);
 }
-#endif unneeded
+#endif /* unneeded */