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