|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */ ! 23: /* ! 24: * Copyright (c) 1993, 1994 Theo de Raadt ! 25: * All rights reserved. ! 26: * ! 27: * Redistribution and use in source and binary forms, with or without ! 28: * modification, are permitted provided that the following conditions ! 29: * are met: ! 30: * 1. Redistributions of source code must retain the above copyright ! 31: * notice unmodified, this list of conditions, and the following ! 32: * disclaimer. ! 33: * 2. Redistributions in binary form must reproduce the above copyright ! 34: * notice, this list of conditions and the following disclaimer in the ! 35: * documentation and/or other materials provided with the distribution. ! 36: * ! 37: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ! 38: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 39: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 40: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ! 41: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 42: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 43: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 44: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 45: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 46: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 47: * SUCH DAMAGE. ! 48: * ! 49: */ ! 50: ! 51: #ifdef NeXT ! 52: /* ! 53: * We use the NetBSD based clist system, it is much more efficient than the ! 54: * old style clist stuff used by free bsd. ! 55: */ ! 56: ! 57: #include <sys/param.h> ! 58: #include <sys/systm.h> ! 59: #include <sys/buf.h> ! 60: #include <sys/ioctl.h> ! 61: #include <sys/tty.h> ! 62: #include <sys/malloc.h> ! 63: ! 64: #include <machine/spl.h> ! 65: ! 66: /* ! 67: * At compile time, choose: ! 68: * There are two ways the TTY_QUOTE bit can be stored. If QBITS is ! 69: * defined we allocate an array of bits -- 1/8th as much memory but ! 70: * setbit(), clrbit(), and isset() take more cpu. If QBITS is ! 71: * undefined, we just use an array of bytes. ! 72: * ! 73: * If TTY_QUOTE functionality isn't required by a line discipline, ! 74: * it can free c_cq and set it to NULL. This speeds things up, ! 75: * and also does not use any extra memory. This is useful for (say) ! 76: * a SLIP line discipline that wants a 32K ring buffer for data ! 77: * but doesn't need quoting. ! 78: */ ! 79: #define QBITS ! 80: ! 81: #ifdef QBITS ! 82: #define QMEM(n) ((((n)-1)/NBBY)+1) ! 83: #else ! 84: #define QMEM(n) (n) ! 85: #endif ! 86: ! 87: ! 88: /* ! 89: * Initialize clists. ! 90: */ ! 91: void ! 92: cinit() ! 93: { ! 94: } ! 95: ! 96: /* ! 97: * Initialize a particular clist. Ok, they are really ring buffers, ! 98: * of the specified length, with/without quoting support. ! 99: */ ! 100: int ! 101: clalloc(clp, size, quot) ! 102: struct clist *clp; ! 103: int size; ! 104: int quot; ! 105: { ! 106: ! 107: MALLOC(clp->c_cs, u_char *, size, M_TTYS, M_WAITOK); ! 108: if (!clp->c_cs) ! 109: return (-1); ! 110: bzero(clp->c_cs, size); ! 111: ! 112: if(quot) { ! 113: MALLOC(clp->c_cq, u_char *, QMEM(size), M_TTYS, M_WAITOK); ! 114: if (!clp->c_cq) { ! 115: FREE(clp->c_cs, M_TTYS); ! 116: return (-1); ! 117: } ! 118: bzero(clp->c_cs, QMEM(size)); ! 119: } else ! 120: clp->c_cq = (u_char *)0; ! 121: ! 122: clp->c_cf = clp->c_cl = (u_char *)0; ! 123: clp->c_ce = clp->c_cs + size; ! 124: clp->c_cn = size; ! 125: clp->c_cc = 0; ! 126: return (0); ! 127: } ! 128: ! 129: void ! 130: clfree(clp) ! 131: struct clist *clp; ! 132: { ! 133: if(clp->c_cs) ! 134: FREE(clp->c_cs, M_TTYS); ! 135: if(clp->c_cq) ! 136: FREE(clp->c_cq, M_TTYS); ! 137: clp->c_cs = clp->c_cq = (u_char *)0; ! 138: } ! 139: ! 140: ! 141: /* ! 142: * Get a character from a clist. ! 143: */ ! 144: int ! 145: getc(clp) ! 146: struct clist *clp; ! 147: { ! 148: register int c = -1; ! 149: int s; ! 150: ! 151: s = spltty(); ! 152: if (clp->c_cc == 0) ! 153: goto out; ! 154: ! 155: c = *clp->c_cf & 0xff; ! 156: if (clp->c_cq) { ! 157: #ifdef QBITS ! 158: if (isset(clp->c_cq, clp->c_cf - clp->c_cs) ) ! 159: c |= TTY_QUOTE; ! 160: #else ! 161: if (*(clp->c_cf - clp->c_cs + clp->c_cq)) ! 162: c |= TTY_QUOTE; ! 163: #endif ! 164: } ! 165: if (++clp->c_cf == clp->c_ce) ! 166: clp->c_cf = clp->c_cs; ! 167: if (--clp->c_cc == 0) ! 168: clp->c_cf = clp->c_cl = (u_char *)0; ! 169: out: ! 170: splx(s); ! 171: return c; ! 172: } ! 173: ! 174: /* ! 175: * Copy clist to buffer. ! 176: * Return number of bytes moved. ! 177: */ ! 178: int ! 179: q_to_b(clp, cp, count) ! 180: struct clist *clp; ! 181: u_char *cp; ! 182: int count; ! 183: { ! 184: register int cc; ! 185: u_char *p = cp; ! 186: int s; ! 187: ! 188: s = spltty(); ! 189: /* optimize this while loop */ ! 190: while (count > 0 && clp->c_cc > 0) { ! 191: cc = clp->c_cl - clp->c_cf; ! 192: if (clp->c_cf >= clp->c_cl) ! 193: cc = clp->c_ce - clp->c_cf; ! 194: if (cc > count) ! 195: cc = count; ! 196: bcopy(clp->c_cf, p, cc); ! 197: count -= cc; ! 198: p += cc; ! 199: clp->c_cc -= cc; ! 200: clp->c_cf += cc; ! 201: if (clp->c_cf == clp->c_ce) ! 202: clp->c_cf = clp->c_cs; ! 203: } ! 204: if (clp->c_cc == 0) ! 205: clp->c_cf = clp->c_cl = (u_char *)0; ! 206: splx(s); ! 207: return p - cp; ! 208: } ! 209: ! 210: /* ! 211: * Return count of contiguous characters in clist. ! 212: * Stop counting if flag&character is non-null. ! 213: */ ! 214: int ! 215: ndqb(clp, flag) ! 216: struct clist *clp; ! 217: int flag; ! 218: { ! 219: int count = 0; ! 220: register int i; ! 221: register int cc; ! 222: int s; ! 223: ! 224: s = spltty(); ! 225: if ((cc = clp->c_cc) == 0) ! 226: goto out; ! 227: ! 228: if (flag == 0) { ! 229: count = clp->c_cl - clp->c_cf; ! 230: if (count <= 0) ! 231: count = clp->c_ce - clp->c_cf; ! 232: goto out; ! 233: } ! 234: ! 235: i = clp->c_cf - clp->c_cs; ! 236: if (flag & TTY_QUOTE) { ! 237: while (cc-- > 0 && !(clp->c_cs[i++] & (flag & ~TTY_QUOTE) || ! 238: isset(clp->c_cq, i))) { ! 239: count++; ! 240: if (i == clp->c_cn) ! 241: break; ! 242: } ! 243: } else { ! 244: while (cc-- > 0 && !(clp->c_cs[i++] & flag)) { ! 245: count++; ! 246: if (i == clp->c_cn) ! 247: break; ! 248: } ! 249: } ! 250: out: ! 251: splx(s); ! 252: return count; ! 253: } ! 254: ! 255: /* ! 256: * Flush count bytes from clist. ! 257: */ ! 258: void ! 259: ndflush(clp, count) ! 260: struct clist *clp; ! 261: int count; ! 262: { ! 263: register int cc; ! 264: int s; ! 265: ! 266: s = spltty(); ! 267: if (count == clp->c_cc) { ! 268: clp->c_cc = 0; ! 269: clp->c_cf = clp->c_cl = (u_char *)0; ! 270: goto out; ! 271: } ! 272: /* optimize this while loop */ ! 273: while (count > 0 && clp->c_cc > 0) { ! 274: cc = clp->c_cl - clp->c_cf; ! 275: if (clp->c_cf >= clp->c_cl) ! 276: cc = clp->c_ce - clp->c_cf; ! 277: if (cc > count) ! 278: cc = count; ! 279: count -= cc; ! 280: clp->c_cc -= cc; ! 281: clp->c_cf += cc; ! 282: if (clp->c_cf == clp->c_ce) ! 283: clp->c_cf = clp->c_cs; ! 284: } ! 285: if (clp->c_cc == 0) ! 286: clp->c_cf = clp->c_cl = (u_char *)0; ! 287: out: ! 288: splx(s); ! 289: } ! 290: ! 291: /* ! 292: * Put a character into the output queue. ! 293: */ ! 294: int ! 295: putc(c, clp) ! 296: int c; ! 297: struct clist *clp; ! 298: { ! 299: register int i; ! 300: int s; ! 301: ! 302: s = spltty(); ! 303: if (clp->c_cc == 0) { ! 304: if (!clp->c_cs) { ! 305: #if DIAGNOSTIC ! 306: //printf("putc: required clalloc\n"); ! 307: #endif ! 308: if(clalloc(clp, 1024, 1)) { ! 309: out: ! 310: splx(s); ! 311: return -1; ! 312: } ! 313: } ! 314: clp->c_cf = clp->c_cl = clp->c_cs; ! 315: } ! 316: ! 317: if (clp->c_cc == clp->c_cn) ! 318: goto out; ! 319: ! 320: *clp->c_cl = c & 0xff; ! 321: i = clp->c_cl - clp->c_cs; ! 322: if (clp->c_cq) { ! 323: #ifdef QBITS ! 324: if (c & TTY_QUOTE) ! 325: setbit(clp->c_cq, i); ! 326: else ! 327: clrbit(clp->c_cq, i); ! 328: #else ! 329: q = clp->c_cq + i; ! 330: *q = (c & TTY_QUOTE) ? 1 : 0; ! 331: #endif ! 332: } ! 333: clp->c_cc++; ! 334: clp->c_cl++; ! 335: if (clp->c_cl == clp->c_ce) ! 336: clp->c_cl = clp->c_cs; ! 337: splx(s); ! 338: return 0; ! 339: } ! 340: ! 341: #ifdef QBITS ! 342: /* ! 343: * optimized version of ! 344: * ! 345: * for (i = 0; i < len; i++) ! 346: * clrbit(cp, off + len); ! 347: */ ! 348: void ! 349: clrbits(cp, off, len) ! 350: u_char *cp; ! 351: int off; ! 352: int len; ! 353: { ! 354: int sby, sbi, eby, ebi; ! 355: register int i; ! 356: u_char mask; ! 357: ! 358: if(len==1) { ! 359: clrbit(cp, off); ! 360: return; ! 361: } ! 362: ! 363: sby = off / NBBY; ! 364: sbi = off % NBBY; ! 365: eby = (off+len) / NBBY; ! 366: ebi = (off+len) % NBBY; ! 367: if (sby == eby) { ! 368: mask = ((1 << (ebi - sbi)) - 1) << sbi; ! 369: cp[sby] &= ~mask; ! 370: } else { ! 371: mask = (1<<sbi) - 1; ! 372: cp[sby++] &= mask; ! 373: ! 374: mask = (1<<ebi) - 1; ! 375: cp[eby] &= ~mask; ! 376: ! 377: for (i = sby; i < eby; i++) ! 378: cp[i] = 0x00; ! 379: } ! 380: } ! 381: #endif ! 382: ! 383: /* ! 384: * Copy buffer to clist. ! 385: * Return number of bytes not transfered. ! 386: */ ! 387: int ! 388: b_to_q(cp, count, clp) ! 389: u_char *cp; ! 390: int count; ! 391: struct clist *clp; ! 392: { ! 393: register int cc; ! 394: register u_char *p = cp; ! 395: int s; ! 396: ! 397: if (count <= 0) ! 398: return 0; ! 399: ! 400: s = spltty(); ! 401: ! 402: if (clp->c_cc == 0) { ! 403: if (!clp->c_cs) { ! 404: #if DIAGNOSTIC ! 405: printf("b_to_q: required clalloc\n"); ! 406: #endif ! 407: if(clalloc(clp, 1024, 1)) ! 408: goto out; ! 409: } ! 410: clp->c_cf = clp->c_cl = clp->c_cs; ! 411: } ! 412: ! 413: if (clp->c_cc == clp->c_cn) ! 414: goto out; ! 415: ! 416: /* optimize this while loop */ ! 417: while (count > 0 && clp->c_cc < clp->c_cn) { ! 418: cc = clp->c_ce - clp->c_cl; ! 419: if (clp->c_cf > clp->c_cl) ! 420: cc = clp->c_cf - clp->c_cl; ! 421: if (cc > count) ! 422: cc = count; ! 423: bcopy(p, clp->c_cl, cc); ! 424: if (clp->c_cq) { ! 425: #ifdef QBITS ! 426: clrbits(clp->c_cq, clp->c_cl - clp->c_cs, cc); ! 427: #else ! 428: bzero(clp->c_cl - clp->c_cs + clp->c_cq, cc); ! 429: #endif ! 430: } ! 431: p += cc; ! 432: count -= cc; ! 433: clp->c_cc += cc; ! 434: clp->c_cl += cc; ! 435: if (clp->c_cl == clp->c_ce) ! 436: clp->c_cl = clp->c_cs; ! 437: } ! 438: out: ! 439: splx(s); ! 440: return count; ! 441: } ! 442: ! 443: static int cc; ! 444: ! 445: /* ! 446: * Given a non-NULL pointer into the clist return the pointer ! 447: * to the next character in the list or return NULL if no more chars. ! 448: * ! 449: * Callers must not allow getc's to happen between firstc's and getc's ! 450: * so that the pointer becomes invalid. Note that interrupts are NOT ! 451: * masked. ! 452: */ ! 453: u_char * ! 454: nextc(clp, cp, c) ! 455: struct clist *clp; ! 456: register u_char *cp; ! 457: int *c; ! 458: { ! 459: ! 460: if (clp->c_cf == cp) { ! 461: /* ! 462: * First time initialization. ! 463: */ ! 464: cc = clp->c_cc; ! 465: } ! 466: if (cc == 0 || cp == NULL) ! 467: return NULL; ! 468: if (--cc == 0) ! 469: return NULL; ! 470: if (++cp == clp->c_ce) ! 471: cp = clp->c_cs; ! 472: *c = *cp & 0xff; ! 473: if (clp->c_cq) { ! 474: #ifdef QBITS ! 475: if (isset(clp->c_cq, cp - clp->c_cs)) ! 476: *c |= TTY_QUOTE; ! 477: #else ! 478: if (*(clp->c_cf - clp->c_cs + clp->c_cq)) ! 479: *c |= TTY_QUOTE; ! 480: #endif ! 481: } ! 482: return cp; ! 483: } ! 484: ! 485: /* ! 486: * Given a non-NULL pointer into the clist return the pointer ! 487: * to the first character in the list or return NULL if no more chars. ! 488: * ! 489: * Callers must not allow getc's to happen between firstc's and getc's ! 490: * so that the pointer becomes invalid. Note that interrupts are NOT ! 491: * masked. ! 492: * ! 493: * *c is set to the NEXT character ! 494: */ ! 495: u_char * ! 496: firstc(clp, c) ! 497: struct clist *clp; ! 498: int *c; ! 499: { ! 500: register u_char *cp; ! 501: ! 502: cc = clp->c_cc; ! 503: if (cc == 0) ! 504: return NULL; ! 505: cp = clp->c_cf; ! 506: *c = *cp & 0xff; ! 507: if(clp->c_cq) { ! 508: #ifdef QBITS ! 509: if (isset(clp->c_cq, cp - clp->c_cs)) ! 510: *c |= TTY_QUOTE; ! 511: #else ! 512: if (*(cp - clp->c_cs + clp->c_cq)) ! 513: *c |= TTY_QUOTE; ! 514: #endif ! 515: } ! 516: return clp->c_cf; ! 517: } ! 518: ! 519: /* ! 520: * Remove the last character in the clist and return it. ! 521: */ ! 522: int ! 523: unputc(clp) ! 524: struct clist *clp; ! 525: { ! 526: unsigned int c = -1; ! 527: int s; ! 528: ! 529: s = spltty(); ! 530: if (clp->c_cc == 0) ! 531: goto out; ! 532: ! 533: if (clp->c_cl == clp->c_cs) ! 534: clp->c_cl = clp->c_ce - 1; ! 535: else ! 536: --clp->c_cl; ! 537: clp->c_cc--; ! 538: ! 539: c = *clp->c_cl & 0xff; ! 540: if (clp->c_cq) { ! 541: #ifdef QBITS ! 542: if (isset(clp->c_cq, clp->c_cl - clp->c_cs)) ! 543: c |= TTY_QUOTE; ! 544: #else ! 545: if (*(clp->c_cf - clp->c_cs + clp->c_cq)) ! 546: c |= TTY_QUOTE; ! 547: #endif ! 548: } ! 549: if (clp->c_cc == 0) ! 550: clp->c_cf = clp->c_cl = (u_char *)0; ! 551: out: ! 552: splx(s); ! 553: return c; ! 554: } ! 555: ! 556: /* ! 557: * Put the chars in the from queue on the end of the to queue. ! 558: */ ! 559: void ! 560: catq(from, to) ! 561: struct clist *from, *to; ! 562: { ! 563: int c; ! 564: ! 565: while ((c = getc(from)) != -1) ! 566: putc(c, to); ! 567: } ! 568: ! 569: #endif /* NeXT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.