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

unix.superglobalmegacorp.com

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