1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)tty_subr.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "systm.h"
  11: #include "buf.h"
  12: #include "ioctl.h"
  13: #include "tty.h"
  14: #include "clist.h"
  15: 
  16: char    cwaiting;
  17: 
  18: /*
  19:  * Character list get/put
  20:  */
  21: getc(p)
  22:     register struct clist *p;
  23: {
  24:     register struct cblock *bp;
  25:     register int c, s;
  26: 
  27:     s = spltty();
  28:     if (p->c_cc <= 0) {
  29:         c = -1;
  30:         p->c_cc = 0;
  31:         p->c_cf = p->c_cl = NULL;
  32:     } else {
  33:         c = *p->c_cf++ & 0377;
  34:         if (--p->c_cc<=0) {
  35:             bp = (struct cblock *)(p->c_cf-1);
  36:             bp = (struct cblock *)((int)bp & ~CROUND);
  37:             p->c_cf = NULL;
  38:             p->c_cl = NULL;
  39:             bp->c_next = cfreelist;
  40:             cfreelist = bp;
  41:             cfreecount += CBSIZE;
  42:             if (cwaiting) {
  43:                 wakeup(&cwaiting);
  44:                 cwaiting = 0;
  45:             }
  46:         } else if (((int)p->c_cf & CROUND) == 0){
  47:             bp = (struct cblock *)(p->c_cf);
  48:             bp--;
  49:             p->c_cf = bp->c_next->c_info;
  50:             bp->c_next = cfreelist;
  51:             cfreelist = bp;
  52:             cfreecount += CBSIZE;
  53:             if (cwaiting) {
  54:                 wakeup(&cwaiting);
  55:                 cwaiting = 0;
  56:             }
  57:         }
  58:     }
  59:     splx(s);
  60:     return (c);
  61: }
  62: 
  63: /*
  64:  * copy clist to buffer.
  65:  * return number of bytes moved.
  66:  */
  67: q_to_b(q, cp, cc)
  68:     register struct clist *q;
  69:     register char *cp;
  70: {
  71:     register struct cblock *bp;
  72:     register int s;
  73:     register nc;
  74:     char *acp;
  75: 
  76:     if (cc <= 0)
  77:         return (0);
  78:     s = spltty();
  79:     if (q->c_cc <= 0) {
  80:         q->c_cc = 0;
  81:         q->c_cf = q->c_cl = NULL;
  82:         splx(s);
  83:         return (0);
  84:     }
  85:     acp = cp;
  86: 
  87:     while (cc) {
  88:         nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
  89:         nc = MIN(nc, cc);
  90:         nc = MIN(nc, q->c_cc);
  91:         (void) bcopy(q->c_cf, cp, (unsigned)nc);
  92:         q->c_cf += nc;
  93:         q->c_cc -= nc;
  94:         cc -= nc;
  95:         cp += nc;
  96:         if (q->c_cc <= 0) {
  97:             bp = (struct cblock *)(q->c_cf - 1);
  98:             bp = (struct cblock *)((int)bp & ~CROUND);
  99:             q->c_cf = q->c_cl = NULL;
 100:             bp->c_next = cfreelist;
 101:             cfreelist = bp;
 102:             cfreecount += CBSIZE;
 103:             if (cwaiting) {
 104:                 wakeup(&cwaiting);
 105:                 cwaiting = 0;
 106:             }
 107:             break;
 108:         }
 109:         if (((int)q->c_cf & CROUND) == 0) {
 110:             bp = (struct cblock *)(q->c_cf);
 111:             bp--;
 112:             q->c_cf = bp->c_next->c_info;
 113:             bp->c_next = cfreelist;
 114:             cfreelist = bp;
 115:             cfreecount += CBSIZE;
 116:             if (cwaiting) {
 117:                 wakeup(&cwaiting);
 118:                 cwaiting = 0;
 119:             }
 120:         }
 121:     }
 122:     splx(s);
 123:     return (cp-acp);
 124: }
 125: 
 126: /*
 127:  * Return count of contiguous characters
 128:  * in clist starting at q->c_cf.
 129:  * Stop counting if flag&character is non-null.
 130:  */
 131: ndqb(q, flag)
 132:     register struct clist *q;
 133: {
 134:     register cc;
 135:     int s;
 136: 
 137:     s = spltty();
 138:     if (q->c_cc <= 0) {
 139:         cc = -q->c_cc;
 140:         goto out;
 141:     }
 142:     cc = ((int)q->c_cf + CBSIZE) & ~CROUND;
 143:     cc -= (int)q->c_cf;
 144:     if (q->c_cc < cc)
 145:         cc = q->c_cc;
 146:     if (flag) {
 147:         register char *p, *end;
 148: 
 149:         p = q->c_cf;
 150:         end = p;
 151:         end += cc;
 152:         while (p < end) {
 153:             if (*p & flag) {
 154:                 cc = (int)p;
 155:                 cc -= (int)q->c_cf;
 156:                 break;
 157:             }
 158:             p++;
 159:         }
 160:     }
 161: out:
 162:     splx(s);
 163:     return (cc);
 164: }
 165: 
 166: /*
 167:  * Flush cc bytes from q.
 168:  */
 169: ndflush(q, cc)
 170:     register struct clist *q;
 171:     register cc;
 172: {
 173:     register struct cblock *bp;
 174:     char *end;
 175:     int rem, s;
 176: 
 177:     s = spltty();
 178:     if (q->c_cc <= 0)
 179:         goto out;
 180:     while (cc>0 && q->c_cc) {
 181:         bp = (struct cblock *)((int)q->c_cf & ~CROUND);
 182:         if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
 183:             end = q->c_cl;
 184:         } else {
 185:             end = (char *)((int)bp + sizeof (struct cblock));
 186:         }
 187:         rem = end - q->c_cf;
 188:         if (cc >= rem) {
 189:             cc -= rem;
 190:             q->c_cc -= rem;
 191:             q->c_cf = bp->c_next->c_info;
 192:             bp->c_next = cfreelist;
 193:             cfreelist = bp;
 194:             cfreecount += CBSIZE;
 195:             if (cwaiting) {
 196:                 wakeup(&cwaiting);
 197:                 cwaiting = 0;
 198:             }
 199:         } else {
 200:             q->c_cc -= cc;
 201:             q->c_cf += cc;
 202:             if (q->c_cc <= 0) {
 203:                 bp->c_next = cfreelist;
 204:                 cfreelist = bp;
 205:                 cfreecount += CBSIZE;
 206:                 if (cwaiting) {
 207:                     wakeup(&cwaiting);
 208:                     cwaiting = 0;
 209:                 }
 210:             }
 211:             break;
 212:         }
 213:     }
 214:     if (q->c_cc <= 0) {
 215:         q->c_cf = q->c_cl = NULL;
 216:         q->c_cc = 0;
 217:     }
 218: out:
 219:     splx(s);
 220: }
 221: 
 222: 
 223: putc(c, p)
 224:     register struct clist *p;
 225: {
 226:     register struct cblock *bp;
 227:     register char *cp;
 228:     register s;
 229: 
 230:     s = spltty();
 231:     if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
 232:         if ((bp = cfreelist) == NULL) {
 233:             splx(s);
 234:             return (-1);
 235:         }
 236:         cfreelist = bp->c_next;
 237:         cfreecount -= CBSIZE;
 238:         bp->c_next = NULL;
 239:         p->c_cf = cp = bp->c_info;
 240:     } else if (((int)cp & CROUND) == 0) {
 241:         bp = (struct cblock *)cp - 1;
 242:         if ((bp->c_next = cfreelist) == NULL) {
 243:             splx(s);
 244:             return (-1);
 245:         }
 246:         bp = bp->c_next;
 247:         cfreelist = bp->c_next;
 248:         cfreecount -= CBSIZE;
 249:         bp->c_next = NULL;
 250:         cp = bp->c_info;
 251:     }
 252:     *cp++ = c;
 253:     p->c_cc++;
 254:     p->c_cl = cp;
 255:     splx(s);
 256:     return (0);
 257: }
 258: 
 259: /*
 260:  * copy buffer to clist.
 261:  * return number of bytes not transfered.
 262:  */
 263: b_to_q(cp, cc, q)
 264:     register char *cp;
 265:     struct clist *q;
 266:     register int cc;
 267: {
 268:     register char *cq;
 269:     register struct cblock *bp;
 270:     register s, nc;
 271:     int acc;
 272: 
 273:     if (cc <= 0)
 274:         return (0);
 275:     acc = cc;
 276:     s = spltty();
 277:     if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
 278:         if ((bp = cfreelist) == NULL)
 279:             goto out;
 280:         cfreelist = bp->c_next;
 281:         cfreecount -= CBSIZE;
 282:         bp->c_next = NULL;
 283:         q->c_cf = cq = bp->c_info;
 284:     }
 285: 
 286:     while (cc) {
 287:         if (((int)cq & CROUND) == 0) {
 288:             bp = (struct cblock *)cq - 1;
 289:             if ((bp->c_next = cfreelist) == NULL)
 290:                 goto out;
 291:             bp = bp->c_next;
 292:             cfreelist = bp->c_next;
 293:             cfreecount -= CBSIZE;
 294:             bp->c_next = NULL;
 295:             cq = bp->c_info;
 296:         }
 297:         nc = MIN(cc, sizeof (struct cblock) - ((int)cq & CROUND));
 298:         (void) bcopy(cp, cq, (unsigned)nc);
 299:         cp += nc;
 300:         cq += nc;
 301:         cc -= nc;
 302:     }
 303: out:
 304:     q->c_cl = cq;
 305:     q->c_cc += acc - cc;
 306:     splx(s);
 307:     return (cc);
 308: }
 309: 
 310: /*
 311:  * Given a non-NULL pointter into the list (like c_cf which
 312:  * always points to a real character if non-NULL) return the pointer
 313:  * to the next character in the list or return NULL if no more chars.
 314:  *
 315:  * Callers must not allow getc's to happen between nextc's so that the
 316:  * pointer becomes invalid.  Note that interrupts are NOT masked.
 317:  */
 318: char *
 319: nextc(p, cp)
 320:     register struct clist *p;
 321:     register char *cp;
 322: {
 323: 
 324:     if (p->c_cc && ++cp != p->c_cl) {
 325:         if (((int)cp & CROUND) == 0)
 326:             return (((struct cblock *)cp)[-1].c_next->c_info);
 327:         return (cp);
 328:     }
 329:     return (0);
 330: }
 331: 
 332: /*
 333:  * Remove the last character in the list and return it.
 334:  */
 335: unputc(p)
 336:     register struct clist *p;
 337: {
 338:     register struct cblock *bp;
 339:     register int c, s;
 340:     struct cblock *obp;
 341: 
 342:     s = spltty();
 343:     if (p->c_cc <= 0)
 344:         c = -1;
 345:     else {
 346:         c = *--p->c_cl;
 347:         if (--p->c_cc <= 0) {
 348:             bp = (struct cblock *)p->c_cl;
 349:             bp = (struct cblock *)((int)bp & ~CROUND);
 350:             p->c_cl = p->c_cf = NULL;
 351:             bp->c_next = cfreelist;
 352:             cfreelist = bp;
 353:             cfreecount += CBSIZE;
 354:         } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
 355:             p->c_cl = (char *)((int)p->c_cl & ~CROUND);
 356:             bp = (struct cblock *)p->c_cf;
 357:             bp = (struct cblock *)((int)bp & ~CROUND);
 358:             while (bp->c_next != (struct cblock *)p->c_cl)
 359:                 bp = bp->c_next;
 360:             obp = bp;
 361:             p->c_cl = (char *)(bp + 1);
 362:             bp = bp->c_next;
 363:             bp->c_next = cfreelist;
 364:             cfreelist = bp;
 365:             cfreecount += CBSIZE;
 366:             obp->c_next = NULL;
 367:         }
 368:     }
 369:     splx(s);
 370:     return (c);
 371: }
 372: 
 373: /*
 374:  * Put the chars in the from que
 375:  * on the end of the to que.
 376:  */
 377: catq(from, to)
 378:     struct clist *from, *to;
 379: {
 380:     char bbuf[CBSIZE*4];
 381:     register s, c;
 382: 
 383:     s = spltty();
 384:     if (to->c_cc == 0) {
 385:         *to = *from;
 386:         from->c_cc = 0;
 387:         from->c_cf = NULL;
 388:         from->c_cl = NULL;
 389:         splx(s);
 390:         return;
 391:     }
 392:     splx(s);
 393:     while (from->c_cc > 0) {
 394:         c = q_to_b(from, bbuf, sizeof bbuf);
 395:         (void) b_to_q(bbuf, c, to);
 396:     }
 397: }
 398: 
 399: #ifdef unneeded
 400: /*
 401:  * Integer (short) get/put using clists.
 402:  * Note dependency on byte order.
 403:  */
 404: typedef u_short word_t;
 405: 
 406: getw(p)
 407:     register struct clist *p;
 408: {
 409:     register int s, c;
 410:     register struct cblock *bp;
 411: 
 412:     if (p->c_cc <= 1)
 413:         return(-1);
 414:     if (p->c_cc & 01) {
 415:         c = getc(p);
 416: #if defined(vax)
 417:         return (c | (getc(p)<<8));
 418: #else
 419:         return (getc(p) | (c<<8));
 420: #endif
 421:     }
 422:     s = spltty();
 423: #if defined(vax)
 424:     c = *((word_t *)p->c_cf);
 425: #else
 426:     c = (((u_char *)p->c_cf)[1] << 8) | ((u_char *)p->c_cf)[0];
 427: #endif
 428:     p->c_cf += sizeof (word_t);
 429:     p->c_cc -= sizeof (word_t);
 430:     if (p->c_cc <= 0) {
 431:         bp = (struct cblock *)(p->c_cf-1);
 432:         bp = (struct cblock *)((int)bp & ~CROUND);
 433:         p->c_cf = NULL;
 434:         p->c_cl = NULL;
 435:         bp->c_next = cfreelist;
 436:         cfreelist = bp;
 437:         cfreecount += CBSIZE;
 438:         if (cwaiting) {
 439:             wakeup(&cwaiting);
 440:             cwaiting = 0;
 441:         }
 442:     } else if (((int)p->c_cf & CROUND) == 0) {
 443:         bp = (struct cblock *)(p->c_cf);
 444:         bp--;
 445:         p->c_cf = bp->c_next->c_info;
 446:         bp->c_next = cfreelist;
 447:         cfreelist = bp;
 448:         cfreecount += CBSIZE;
 449:         if (cwaiting) {
 450:             wakeup(&cwaiting);
 451:             cwaiting = 0;
 452:         }
 453:     }
 454:     splx(s);
 455:     return (c);
 456: }
 457: 
 458: putw(c, p)
 459:     register struct clist *p;
 460:     word_t c;
 461: {
 462:     register s;
 463:     register struct cblock *bp;
 464:     register char *cp;
 465: 
 466:     s = spltty();
 467:     if (cfreelist==NULL) {
 468:         splx(s);
 469:         return(-1);
 470:     }
 471:     if (p->c_cc & 01) {
 472: #if defined(vax)
 473:         (void) putc(c, p);
 474:         (void) putc(c>>8, p);
 475: #else
 476:         (void) putc(c>>8, p);
 477:         (void) putc(c, p);
 478: #endif
 479:     } else {
 480:         if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
 481:             if ((bp = cfreelist) == NULL) {
 482:                 splx(s);
 483:                 return (-1);
 484:             }
 485:             cfreelist = bp->c_next;
 486:             cfreecount -= CBSIZE;
 487:             bp->c_next = NULL;
 488:             p->c_cf = cp = bp->c_info;
 489:         } else if (((int)cp & CROUND) == 0) {
 490:             bp = (struct cblock *)cp - 1;
 491:             if ((bp->c_next = cfreelist) == NULL) {
 492:                 splx(s);
 493:                 return (-1);
 494:             }
 495:             bp = bp->c_next;
 496:             cfreelist = bp->c_next;
 497:             cfreecount -= CBSIZE;
 498:             bp->c_next = NULL;
 499:             cp = bp->c_info;
 500:         }
 501: #if defined(vax)
 502:         *(word_t *)cp = c;
 503: #else
 504:         ((u_char *)cp)[0] = c>>8;
 505:         ((u_char *)cp)[1] = c;
 506: #endif
 507:         p->c_cl = cp + sizeof (word_t);
 508:         p->c_cc += sizeof (word_t);
 509:     }
 510:     splx(s);
 511:     return (0);
 512: }
 513: #endif unneeded

Defined functions

b_to_q defined in line 263; used 5 times
catq defined in line 377; used 2 times
getc defined in line 21; used 3 times
getw defined in line 406; never used
nextc defined in line 318; used 5 times
putw defined in line 458; never used
q_to_b defined in line 67; used 2 times
unputc defined in line 335; used 8 times

Defined variables

cwaiting defined in line 16; used 24 times

Defined typedef's

word_t defined in line 404; used 7 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2042
Valid CSS Valid XHTML 1.0 Strict