Annotation of 43BSDReno/sys/kern/tty_subr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.