-/* tty_subr.c 4.14 82/02/08 */
+/*
+ * 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;
* Character list get/put
*/
getc(p)
-register struct clist *p;
+ register struct clist *p;
{
register struct cblock *bp;
register int c, s;
- s = spl5();
+ s = spltty();
if (p->c_cc <= 0) {
c = -1;
p->c_cc = 0;
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;
}
}
splx(s);
- return(c);
+ return (c);
}
-#if 0
/*
* copy clist to buffer.
* 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 nc;
char *acp;
if (cc <= 0)
- return(0);
- s = spl5();
+ return (0);
+ 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;
- 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;
}
}
splx(s);
- return(cp-acp);
+ return (cp-acp);
}
-#endif
/*
* Return count of contiguous characters
* 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 = spl5();
+ s = spltty();
if (q->c_cc <= 0) {
cc = -q->c_cc;
goto out;
}
out:
splx(s);
- return(cc);
+ return (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 = spl5();
- if (q->c_cc < 0) {
- printf("neg q flush\n");
+ s = spltty();
+ if (q->c_cc <= 0)
goto out;
- }
- if (q->c_cc == 0) {
- 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)) {
putc(c, p)
-register struct clist *p;
+ register struct clist *p;
{
register struct cblock *bp;
register char *cp;
register s;
- s = spl5();
+ s = spltty();
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;
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;
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)
-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 s, acc;
+ register s, nc;
+ int acc;
if (cc <= 0)
- return(0);
+ return (0);
acc = cc;
-
-
- s = spl5();
+ s = spltty();
if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
if ((bp = cfreelist) == NULL)
goto out;
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;
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;
- q->c_cc += acc-cc;
+ q->c_cc += acc - cc;
splx(s);
- return(cc);
+ return (cc);
}
/*
*/
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) {
* 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;
- s = spl5();
+ s = spltty();
if (p->c_cc <= 0)
c = -1;
else {
/*
* 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)
-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);
+ }
}
-#include "dmc.h"
-#if NDMC > 0
+#ifdef unneeded
/*
- * integer (2-byte) get/put
- * using clists
+ * Integer (short) get/put using clists.
*/
+typedef u_short word_t;
+
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);
- 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
+ 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)
-register struct clist *p;
+ register struct clist *p;
+ word_t c;
{
register s;
+ register struct cblock *bp;
+ register char *cp;
- s = spl5();
+ s = spltty();
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);
- return(0);
+ return (0);
}
-#endif
+#endif unneeded