Annotation of researchv9/sys/dev/mesg.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  message processor-- written data turns into control, read control
                      3:  *   turns into data
                      4:  *  rmesg is just the opposite
                      5:  */
                      6: 
                      7: #include "../h/param.h"
                      8: #include "../h/systm.h"
                      9: #include "../h/stream.h"
                     10: #include "../h/conf.h"
                     11: #include "mesg.h"
                     12: 
                     13: #define        MS_OPEN 01
                     14: #define        MS_DEL  02
                     15: 
                     16: #define        MS_STOP 010
                     17: #define        MS_IOCTL 020
                     18: 
                     19: struct block *msgcollect();
                     20: int    msctodput(), msctodsrv(), msdtocput(), msdtocsrv(), msgopen(), rmsgopen(),
                     21:        msgclose(), rmsgclose();
                     22: struct qinit msgrinit = { msctodput, msctodsrv, msgopen, msgclose, 128, 65 };
                     23: struct qinit msgwinit = { msdtocput, msdtocsrv, msgopen, msgclose, 128, 65 };
                     24: struct streamtab msginfo = { &msgrinit, &msgwinit };
                     25: 
                     26: struct qinit rmsgrinit = { msdtocput, msdtocsrv, rmsgopen, rmsgclose, 128, 65 };
                     27: struct qinit rmsgwinit = { msctodput, msctodsrv, rmsgopen, rmsgclose, 128, 65 };
                     28: struct streamtab rmsginfo = { &rmsgrinit, &rmsgwinit };
                     29: 
                     30: struct imesg {
                     31:        char type;
                     32:        char msflag;
                     33:        short size;
                     34: } mesg[NMESG];
                     35: 
                     36: msgopen(q, dev)
                     37: register struct queue *q;
                     38: {
                     39:        register struct imesg *mp;
                     40: 
                     41:        if (WR(q)->ptr)
                     42:                return(1);
                     43:        for (mp = mesg; mp->msflag&MS_OPEN; mp++)
                     44:                if (mp >= &mesg[NMESG-1])
                     45:                        return(0);
                     46:        mp->msflag = MS_OPEN;
                     47:        mp->size = 0;
                     48:        WR(q)->ptr = (caddr_t)mp;
                     49:        WR(q)->flag |= QNOENB;
                     50:        q->flag |= QDELIM;
                     51:        return(1);
                     52: }
                     53: 
                     54: rmsgopen(q, dev)
                     55: register struct queue *q;
                     56: {
                     57:        register struct imesg *mp;
                     58: 
                     59:        if (q->ptr)
                     60:                return(1);
                     61:        for (mp = mesg; mp->msflag&MS_OPEN; mp++)
                     62:                if (mp >= &mesg[NMESG-1])
                     63:                        return(0);
                     64:        mp->msflag = MS_OPEN;
                     65:        mp->size = 0;
                     66:        q->ptr = (caddr_t)mp;
                     67:        q->flag |= QNOENB;
                     68:        q->flag |= QDELIM;
                     69:        return(1);
                     70: }
                     71: 
                     72: msgclose(q)
                     73: register struct queue *q;
                     74: {
                     75:        if (WR(q)->ptr)
                     76:                ((struct imesg *)WR(q)->ptr)->msflag = 0;
                     77: }
                     78: 
                     79: rmsgclose(q)
                     80: register struct queue *q;
                     81: {
                     82:        if (q->ptr)
                     83:                ((struct imesg *)q->ptr)->msflag = 0;
                     84: }
                     85: 
                     86: msctodput(q, bp)
                     87: register struct queue *q;
                     88: register struct block *bp;
                     89: {
                     90:        register struct imesg *mp = (struct imesg *)(OTHERQ(q)->ptr);
                     91:        register struct queue *bq = backq(q);
                     92: 
                     93:        /* propagate changes in delimiter status */
                     94:        if (mp->msflag&MS_DEL) {
                     95:                if ((bq->flag&QDELIM) == 0) {
                     96:                        mp->msflag &= ~MS_DEL;
                     97:                        putctl(q, M_NDEL);
                     98:                }
                     99:        } else {
                    100:                if (bq->flag&QDELIM) {
                    101:                        mp->msflag |= MS_DEL;
                    102:                        putctl(q, M_YDEL);
                    103:                }
                    104:        }
                    105:        if (bp->type==M_STOP) {
                    106:                freeb(bp);
                    107:                mp->msflag |= MS_STOP;
                    108:                return;
                    109:        }
                    110:        if (bp->type>=QPCTL) {          /* including M_START */
                    111:                if (bp->type==M_START)
                    112:                        freeb(bp);
                    113:                else {
                    114:                        /* ioctl transparency */
                    115:                        if (mp->msflag & MS_IOCTL
                    116:                         && (bp->type==M_IOCACK || bp->type==M_IOCNAK)) {
                    117:                                (*q->next->qinfo->putp)(q->next, bp);
                    118:                                mp->msflag &=~ MS_IOCTL;
                    119:                                return;
                    120:                        }
                    121:                        putq(q, bp);
                    122:                }
                    123:                mp->msflag &=~ MS_STOP;
                    124:                qenable(q);
                    125:                return;
                    126:        }
                    127:        putq(q, bp);
                    128:        /* enable if we don't have delimiters */
                    129:        if ((bq->flag&QDELIM) == 0)
                    130:                qenable(q);
                    131:        return;
                    132: }
                    133: 
                    134: msctodsrv(q)
                    135: register struct queue *q;
                    136: {
                    137:        register struct block *bp, *hbp;
                    138:        register struct imesg *mp = (struct imesg *)OTHERQ(q)->ptr;
                    139:        register type;
                    140:        register size;
                    141: 
                    142:        for (;;) {
                    143:                if (q->next->flag & QFULL || mp->msflag & MS_STOP)
                    144:                        return;
                    145:                if ((bp = getq(q)) == NULL)
                    146:                        return;
                    147:                if ((hbp = allocb(MSGHLEN)) == NULL) {
                    148:                        putbq(q, bp);
                    149:                        return;
                    150:                }
                    151:                ((struct mesg *)(hbp->wptr))->magic = MSGMAGIC;
                    152:                ((struct mesg *)(hbp->wptr))->type = type = bp->type;
                    153:                size = bp->wptr - bp->rptr;
                    154:                ((struct mesg *)(hbp->wptr))->losize = size;
                    155:                ((struct mesg *)(hbp->wptr))->hisize = size>>8;
                    156:                hbp->wptr += MSGHLEN;
                    157:                (*q->next->qinfo->putp)(q->next, hbp);
                    158:                bp->type = M_DATA;
                    159:                if (bp->wptr > bp->rptr)
                    160:                        (*q->next->qinfo->putp)(q->next, bp);
                    161:                else
                    162:                        freeb(bp);
                    163:                putctl(q->next, M_DELIM);
                    164:                if (type == M_HANGUP)
                    165:                        putctl(q->next, M_HANGUP);
                    166:        }
                    167: }
                    168: 
                    169: msdtocput(q, bp)
                    170: register struct queue *q;
                    171: register struct block *bp;
                    172: {
                    173:        switch (bp->type) {
                    174: 
                    175:        default:
                    176:                freeb(bp);
                    177:                return;
                    178: 
                    179:        case M_FLUSH:
                    180:                flushq(OTHERQ(q), 1);
                    181:        case M_IOCACK:
                    182:        case M_IOCNAK:
                    183:        case M_HANGUP:
                    184:                (*q->next->qinfo->putp)(q->next, bp);
                    185:                return;
                    186: 
                    187:        case M_DATA:
                    188:        case M_IOCTL:
                    189:                putq(q, bp);
                    190:                qenable(q);
                    191:                return;
                    192:        }
                    193: }
                    194: 
                    195: msdtocsrv(q)
                    196: register struct queue *q;
                    197: {
                    198:        register struct block *bp;
                    199:        register struct imesg *mp = (struct imesg *)q->ptr;
                    200: 
                    201:        for (;;) {
                    202:                if (q->next->flag & QFULL)
                    203:                        return;
                    204:                if (mp->size == 0) {            /* Start of message */
                    205:                        bp = msgcollect(q, MSGHLEN, 0, 1);
                    206:                        if (bp == NULL)
                    207:                                return;
                    208:                        mp->size = ((struct mesg *)bp->rptr)->losize;
                    209:                        mp->size += ((struct mesg *)bp->rptr)->hisize<<8;
                    210:                        mp->type = ((struct mesg *)bp->rptr)->type;
                    211:                        /* magic ok; was checked in msgcollect */
                    212:                        if (mp->size < 0)
                    213:                                mp->size = 0;
                    214:                        if (mp->size==0) {
                    215:                                bp->type = mp->type;
                    216:                                bp->rptr = bp->wptr;
                    217:                                if (bp->type==M_YDEL)
                    218:                                        q->flag |= QDELIM;
                    219:                                else if (bp->type==M_NDEL)
                    220:                                        q->flag &= ~QDELIM;
                    221:                                (*q->next->qinfo->putp)(q->next, bp);
                    222:                                continue;
                    223:                        }
                    224:                        freeb(bp);
                    225:                }
                    226:                bp = msgcollect(q, mp->size, mp->type == M_DATA, 0);
                    227:                if (bp == NULL)
                    228:                        return;
                    229:                bp->type = mp->type;
                    230:                mp->size -= bp->wptr - bp->rptr;
                    231:                (*q->next->qinfo->putp)(q->next, bp);
                    232:        }
                    233: }
                    234: 
                    235: long ms_badmag;
                    236: 
                    237: struct block *
                    238: msgcollect(q, size, isdata, findmag)
                    239: register struct queue *q;
                    240: {
                    241:        register struct block *nbp, *bp;
                    242:        register ninb;
                    243:        register struct imesg *mp = (struct imesg *)q->ptr;
                    244: 
                    245:        if (findmag == 0) {
                    246:                if ((bp = getq(q)) == NULL)
                    247:                        return (NULL);
                    248:        }
                    249:        else {
                    250:                while ((bp = getq(q)) != NULL) {
                    251:                        if (bp->type != M_DATA) {
                    252:                                /* prevent the ack from being turned to data */
                    253:                                if (bp->type==M_IOCTL)
                    254:                                        mp->msflag |= MS_IOCTL;
                    255:                                (*q->next->qinfo->putp)(q->next, bp);
                    256:                                continue;
                    257:                        }
                    258:                        while (bp->rptr < bp->wptr-1) {
                    259:                                if (bp->rptr[1] == MSGMAGIC)
                    260:                                        goto gotmagic;
                    261:                                bp->rptr++;
                    262:                                ms_badmag++;
                    263:                        }
                    264:                        freeb(bp);
                    265:                }
                    266:                if (bp == NULL)
                    267:                        return (NULL);
                    268:        }
                    269: gotmagic:
                    270:        nbp = allocb(size);
                    271:        if (nbp == NULL) {
                    272:                putbq(q, bp);
                    273:                return(NULL);
                    274:        }
                    275:        if (size > nbp->lim - nbp->wptr)
                    276:                size = nbp->lim - nbp->wptr;
                    277:        while (size) {
                    278:                if (bp->type != M_DATA) {
                    279:                        /* prevent the ack from being turned to data */
                    280:                        if (bp->type==M_IOCTL)
                    281:                                mp->msflag |= MS_IOCTL;
                    282:                        (*q->next->qinfo->putp)(q->next, bp);
                    283:                        if ((bp = getq(q)) == NULL)
                    284:                                break;
                    285:                        continue;
                    286:                }
                    287:                ninb = bp->wptr - bp->rptr;
                    288:                if (ninb > size) {
                    289:                        bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, size);
                    290:                        nbp->wptr += size;
                    291:                        bp->rptr += size;
                    292:                        size = 0;
                    293:                        putbq(q, bp);
                    294:                        break;
                    295:                }
                    296:                bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, ninb);
                    297:                size -= ninb;
                    298:                nbp->wptr += ninb;
                    299:                freeb(bp);
                    300:                if (size == 0)
                    301:                        break;
                    302:                if ((bp = getq(q)) == NULL)
                    303:                        break;
                    304:        }
                    305:        if (nbp->rptr >= nbp->wptr) {
                    306:                freeb(nbp);
                    307:                return(NULL);
                    308:        }
                    309:        if (size==0 || isdata)
                    310:                return(nbp);
                    311:        putbq(q, nbp);
                    312:        return(NULL);
                    313: }

unix.superglobalmegacorp.com

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