Annotation of coherent/b/STREAMS/conf/dump/src/dump.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * The code in this file is taken from the example dump module listing in
        !             3:  * Appendix B of the STREAMS Programmer's Guide for System V, Release 4 Multi-
        !             4:  * Processor (Intel Edition). The overall structure of the code has been
        !             5:  * retained, with some editing to reflect local coding standards, additional
        !             6:  * commentary, and to bring the code up to SVR4MP DDI/DKI standards.
        !             7:  */
        !             8: 
        !             9: #define        _DDI_DKI        1
        !            10: #define        _SYSV4          1
        !            11: 
        !            12: #include <common/ccompat.h>
        !            13: #include <sys/inline.h>
        !            14: #include <sys/file.h>
        !            15: #include <sys/errno.h>
        !            16: #include <stddef.h>
        !            17: 
        !            18: /*
        !            19:  * DUMP Module. This module prints data and ioctls going to and from a device
        !            20:  * in real time. Printout is on the console. Usage is to push it on a stream
        !            21:  * between any other modules.
        !            22:  *
        !            23:  * It accepts two ioctls:
        !            24:  *     DUMP_VERB       Verbose printing of M_DATA (default)
        !            25:  *     DUMP_TERSE      Terse printing of data
        !            26:  *
        !            27:  * The messages it prints begin with "I:" for incoming, "O:" for outgoing
        !            28:  * data. "Ci" or "Co" are for non-data (control) messages. Data is printed in
        !            29:  * character or hexadecimal format delimited by {{ and }} at message
        !            30:  * boundaries.
        !            31:  */
        !            32: 
        !            33: #include "sys/types.h"
        !            34: #include "sys/stream.h"
        !            35: #include "sys/cmn_err.h"
        !            36: #include "dump.h"
        !            37: 
        !            38: static struct module_info dumprinfo = {
        !            39:        0x6475, "dump", 0, INFPSZ, 0, 0
        !            40: };
        !            41: static struct module_info dumpwinfo = {
        !            42:        0x6475, "dump", 0, INFPSZ, 0, 0
        !            43: };
        !            44: 
        !            45: 
        !            46: static int     dumpopen        __PROTO ((queue_t * q, dev_t * devp, int flag,
        !            47:                                          int sflag, cred_t * credp));
        !            48: static int     dumpclose       __PROTO ((queue_t * q, int flag,
        !            49:                                          cred_t * credp));
        !            50: static void    dumpwput        __PROTO ((queue_t * q, mblk_t * mp));
        !            51: static         void    dumprput        __PROTO ((queue_t * q, mblk_t * mp));
        !            52: 
        !            53: static struct qinit rinit = {
        !            54:        dumprput, NULL, dumpopen, dumpclose, NULL, & dumprinfo, NULL
        !            55: };
        !            56: static struct qinit winit = {
        !            57:        dumpwput, NULL, NULL, NULL, NULL, & dumpwinfo, NULL
        !            58: };
        !            59: 
        !            60: struct streamtab dumpinfo = {
        !            61:        & rinit, & winit, NULL, NULL
        !            62: };
        !            63: 
        !            64: int            dumpdevflag = 0;
        !            65: 
        !            66: 
        !            67: /*
        !            68:  * Gather information from this data message and print it. The caller deals
        !            69:  * with actually forwarding the data message.
        !            70:  */
        !            71: 
        !            72: #if    __USE_PROTO__
        !            73: __LOCAL__ void (dumpgather) (queue_t * q, mblk_t * mp, dm_dir_t dir)
        !            74: #else
        !            75: __LOCAL__ void
        !            76: dumpgather __ARGS ((q, mp, dir))
        !            77: queue_t              * q;
        !            78: mblk_t       * mp;
        !            79: dm_dir_t       dir;
        !            80: #endif
        !            81: {
        !            82:        struct dm_str * d = (struct dm_str *) q->q_ptr;
        !            83:        pl_t            prev_pl;
        !            84:        mblk_t        * tmp;
        !            85:        unsigned long   counter;
        !            86:        char            junk [2];
        !            87: 
        !            88:        /*
        !            89:         * Check state and print direction indication when it changes.
        !            90:         */
        !            91: 
        !            92:        if (d->dm_dir != dir) {
        !            93: 
        !            94:                d->dm_dir = dir;
        !            95:                cmn_err (CE_CONT, dir == D_IN ? "^\nIN:" : "^\nOUT:");
        !            96:        }
        !            97: 
        !            98:        if (mp->b_datap == NULL ||
        !            99:            (mp->b_rptr == mp->b_wptr && mp->b_cont == NULL)) {
        !           100:                /*
        !           101:                 * Zero-length messages are treated specially in most streams,
        !           102:                 * note them specially.
        !           103:                 */
        !           104: 
        !           105:                cmn_err (CE_CONT, "^DUMP: Zero-length data message\n");
        !           106:                return;
        !           107:        }
        !           108: 
        !           109:        cmn_err (CE_CONT, "^ {{");
        !           110: 
        !           111:        tmp = mp;
        !           112:        counter = 0;
        !           113:        junk [1] = 0;
        !           114: 
        !           115:        prev_pl = splstr ();
        !           116: 
        !           117:        do {
        !           118:                unsigned char * readp;
        !           119: 
        !           120:                if ((d->dm_flags & D_VERB) == 0) {
        !           121: 
        !           122:                        counter += tmp->b_wptr - tmp->b_rptr;
        !           123:                        continue;
        !           124:                }
        !           125: 
        !           126:                for (readp = tmp->b_rptr ; readp < tmp->b_wptr ; readp ++)
        !           127:                        if ((junk [0] = * readp) >= ' ' && junk [0] <= '~')
        !           128:                                cmn_err (CE_CONT, "^ %s", junk);
        !           129:                        else
        !           130:                                cmn_err (CE_CONT, "^ 0x%x", junk [0]);
        !           131: 
        !           132:        } while ((tmp = tmp->b_cont) != NULL &&
        !           133:                 tmp->b_datap->db_type == M_DATA);
        !           134: 
        !           135: 
        !           136:        if ((d->dm_flags & D_VERB) == 0)
        !           137:                cmn_err (CE_CONT, "^ %d", counter);
        !           138: 
        !           139:        cmn_err (CE_CONT, "^ }} ");
        !           140: 
        !           141:        if (tmp != NULL)
        !           142:                cmn_err (CE_CONT, "^\nDUMP: non-data b_cont\n");
        !           143: 
        !           144:        splx (prev_pl);
        !           145: }
        !           146: 
        !           147: 
        !           148: /*
        !           149:  * Completely handle one of our ioctl () calls, including the qreply () of the
        !           150:  * message.
        !           151:  */
        !           152: 
        !           153: #if    __USE_PROTO__
        !           154: __LOCAL__ void (dumpioc) (queue_t * q, mblk_t * mp)
        !           155: #else
        !           156: __LOCAL__ void
        !           157: dumpioc __ARGS ((q, mp))
        !           158: queue_t              * q;
        !           159: mblk_t       * mp;
        !           160: #endif
        !           161: {
        !           162:        struct iocblk * iocp = (struct iocblk *) mp->b_rptr;
        !           163:        struct dm_str * d = (struct dm_str *) q->q_ptr;
        !           164: 
        !           165:        cmn_err (CE_CONT, "^DUMP: own ioctl is ");
        !           166: 
        !           167:        switch (iocp->ioc_cmd) {
        !           168: 
        !           169:        case DUMP_VERB:
        !           170:                d->dm_flags |= D_VERB;
        !           171:                cmn_err (CE_CONT, "^DUMP_VERB\n");
        !           172: 
        !           173:                mp->b_datap->db_type = M_IOCACK;
        !           174:                break;
        !           175: 
        !           176:        case DUMP_TERSE:
        !           177:                d->dm_flags &= ~ D_VERB;
        !           178:                cmn_err (CE_CONT, "^DUMP_TERSE\n");
        !           179: 
        !           180:                mp->b_datap->db_type = M_IOCACK;
        !           181:                break;
        !           182: 
        !           183:        default:
        !           184:                cmn_err (CE_CONT, "^ unknown, %x\n", iocp->ioc_cmd);
        !           185: 
        !           186:                mp->b_datap->db_type = M_IOCNAK;
        !           187:                break;
        !           188:        }
        !           189: 
        !           190:        iocp->ioc_count = 0;
        !           191:        qreply (q, mp);
        !           192: }
        !           193: 
        !           194: 
        !           195: /*
        !           196:  * Display information about control messages.
        !           197:  */
        !           198: 
        !           199: #if    __USE_PROTO__
        !           200: __LOCAL__ void (dumpctl) (queue_t * q, mblk_t * mp, dm_dir_t dir)
        !           201: #else
        !           202: __LOCAL__ void
        !           203: dumpctl __ARGS ((q, mp, dir))
        !           204: queue_t              * q;
        !           205: mblk_t       * mp;
        !           206: dm_dir_t       dir;
        !           207: #endif
        !           208: {
        !           209:        __CONST__ char * tmp = NULL;
        !           210: 
        !           211:        cmn_err (CE_CONT, "^\nC%s: M_", dir == D_IN ? "i" : "o");
        !           212: 
        !           213:        switch (mp->b_datap->db_type) {
        !           214: 
        !           215:                /* just in case */
        !           216:        case M_DATA:    tmp = "DATA";   break;
        !           217: 
        !           218:        case M_READ:    tmp = "READ";   break;
        !           219: 
        !           220:        case M_IOCTL:   tmp = "IOCTL";  break;
        !           221: 
        !           222:        case M_IOCACK:  tmp = "IOCACK"; break;
        !           223: 
        !           224:        case M_IOCNAK:  tmp = "IOCNAK"; break;
        !           225: 
        !           226:        case M_IOCDATA: tmp = "IOCDATA"; break;
        !           227: 
        !           228:        case M_CTL:     tmp = "CTL";    break;
        !           229: 
        !           230:        case M_PROTO:   tmp = "PROTO";  break;
        !           231: 
        !           232:        case M_PCPROTO: tmp = "PCPROTO"; break;
        !           233: 
        !           234:        case M_BREAK:   tmp = "BREAK";  break;
        !           235: 
        !           236:        case M_DELAY:   tmp = "DELAY";  break;
        !           237: 
        !           238:        case M_PASSFP:  tmp = "PASSFP"; break;
        !           239: 
        !           240:        case M_SETOPTS: tmp = "SETOPTS"; break;
        !           241: 
        !           242:        case M_ERROR:   tmp = "ERROR";  break;
        !           243: 
        !           244:        case M_HANGUP:  tmp = "HANGUP"; break;
        !           245: 
        !           246:        case M_FLUSH:   tmp = "FLUSH";  break;
        !           247: 
        !           248:        case M_COPYOUT: tmp = "COPYOUT"; break;
        !           249: 
        !           250:        case M_COPYIN:  tmp = "COPYIN"; break;
        !           251: 
        !           252:        case M_START:   tmp = "START";  break;
        !           253: 
        !           254:        case M_STOP:    tmp = "STOP";   break;
        !           255: 
        !           256:        case M_STARTI:  tmp = "STARTI"; break;
        !           257: 
        !           258:        case M_STOPI:   tmp = "STOPI";  break;
        !           259: 
        !           260:        case M_SIG:
        !           261:                cmn_err (CE_CONT, "^SIG (%d) ", * mp->b_rptr);
        !           262:                break;
        !           263: 
        !           264:        case M_PCSIG:
        !           265:                cmn_err (CE_CONT, "^PCSIG (%d) ", * mp->b_rptr);
        !           266:                break;
        !           267: 
        !           268:        default:
        !           269:                cmn_err (CE_CONT, "^Unknown! (0x%x) ", mp->b_datap->db_type);
        !           270:                break;
        !           271:        }
        !           272: 
        !           273:        if (tmp != NULL)
        !           274:                cmn_err (CE_CONT, "^%s", tmp);
        !           275: 
        !           276:        /*
        !           277:         * Reset the direction indicator so the next data message will print
        !           278:         * the direction it is headed in.
        !           279:         */
        !           280: 
        !           281:        ((struct dm_str *) q->q_ptr)->dm_dir = D_NONE;
        !           282: }
        !           283: 
        !           284: 
        !           285: /*
        !           286:  * Display information about generally-known ioctl ()s. Feel free to add more
        !           287:  * knowledge to this to suit your application.
        !           288:  */
        !           289: 
        !           290: #if    __USE_PROTO__
        !           291: __LOCAL__ void (dumpshow) (mblk_t * __NOTUSED (mp), int cmd)
        !           292: #else
        !           293: __LOCAL__ void
        !           294: dumpshow __ARGS ((mp, cmd))
        !           295: mblk_t       * mp;
        !           296: int            cmd;
        !           297: #endif
        !           298: {
        !           299:        switch (cmd) {
        !           300: 
        !           301:        default:
        !           302:                return;
        !           303:        }
        !           304: }
        !           305: 
        !           306: 
        !           307: /*
        !           308:  * Open a dump filter.
        !           309:  */
        !           310: 
        !           311: #if    __USE_PROTO__
        !           312: int dumpopen (queue_t * q, dev_t * __NOTUSED (devp), int flag,
        !           313:              int __NOTUSED (sflag), cred_t * __NOTUSED (credp))
        !           314: #else
        !           315: int dumpopen (q, devp, flag, sflag, credp)
        !           316: queue_t              * q;
        !           317: dev_t        * devp;
        !           318: int            flag;
        !           319: int            sflag;
        !           320: cred_t       * credp;
        !           321: #endif
        !           322: {
        !           323:        int             i;
        !           324: 
        !           325:        if (q->q_ptr != NULL) {
        !           326: 
        !           327:                cmn_err (CE_CONT, "^DUMP: re-open slot %d\n",
        !           328:                         (struct dm_str *) q->q_ptr - dm_users);
        !           329: 
        !           330:                if ((flag & FNDELAY) != 0)
        !           331:                        cmn_err (CE_CONT, "^DUMP: reopen, NDELAY set\n");
        !           332:                if ((flag & FNONBLOCK) != 0)
        !           333:                        cmn_err (CE_CONT, "^DUMP: reopen, NONBLOCK set\n");
        !           334: 
        !           335:                qprocson (q);
        !           336:                return 0;
        !           337:        }
        !           338: 
        !           339:        /*
        !           340:         * Search for a slot to use. We depend on the single-threading of
        !           341:         * driver open routines to protect this code, and the complementary
        !           342:         * code in dumpclose ()
        !           343:         */
        !           344: 
        !           345:        for (i = 0 ; i < dm_ucnt ; i ++) {
        !           346: 
        !           347:                if (dm_users [i].dm_use == D_FREE) {
        !           348: 
        !           349:                        dm_users [i].dm_use = D_USED;
        !           350:                        dm_users [i].dm_dir = D_NONE;
        !           351:                        dm_users [i].dm_flags = D_VERB;
        !           352: 
        !           353:                        WR (q)->q_ptr = q->q_ptr = (_VOID *) & dm_users [i];
        !           354: 
        !           355:                        cmn_err (CE_CONT, "^DUMP: flag = %d\n", flag);
        !           356: 
        !           357:                        if ((flag & FNDELAY) != 0)
        !           358:                                cmn_err (CE_CONT, "^DUMP: open, NDELAY set\n");
        !           359:                        if ((flag & FNONBLOCK) != 0)
        !           360:                                cmn_err (CE_CONT, "^DUMP: open, NONBLOCK set\n");
        !           361: 
        !           362:                        qprocson (q);
        !           363:                        return 0;
        !           364:                }
        !           365:        }
        !           366: 
        !           367:         return EAGAIN;
        !           368: }
        !           369: 
        !           370: 
        !           371: /*
        !           372:  * Close an entry and deallocate the control slot.
        !           373:  */
        !           374: 
        !           375: #if    __USE_PROTO__
        !           376: int (dumpclose) (queue_t * q, int __NOTUSED (flag),
        !           377:                 cred_t * __NOTUSED (credp))
        !           378: #else
        !           379: int
        !           380: dumpclose (q, flag, credp)
        !           381: queue_t              * q;
        !           382: int            flag;
        !           383: cred_t       * credp;
        !           384: #endif
        !           385: {
        !           386:        struct dm_str * d = (struct dm_str *) q->q_ptr;
        !           387: 
        !           388:        d->dm_use = D_FREE;
        !           389:        d->dm_flags = 0;
        !           390: 
        !           391:        WR (q)->q_ptr = q->q_ptr = NULL;
        !           392: 
        !           393:        cmn_err (CE_CONT, "^\nDUMP: end trace\n");
        !           394:        qprocsoff (q);
        !           395:        return 0;
        !           396: }
        !           397: 
        !           398: 
        !           399: /*
        !           400:  * Put procedure for write side of module. Gathers data from all passing
        !           401:  * M_DATA messages. Calls routine to handle ioctl calls.
        !           402:  */
        !           403: 
        !           404: #if    __USE_PROTO__
        !           405: void dumpwput (queue_t * q, mblk_t * mp)
        !           406: #else
        !           407: void
        !           408: dumpwput (q, mp)
        !           409: queue_t              * q;
        !           410: mblk_t       * mp;
        !           411: #endif
        !           412: {
        !           413:        if (mp->b_datap->db_type == M_IOCTL) {
        !           414:                struct iocblk * iocp = (struct iocblk *) mp->b_rptr;
        !           415:                struct dm_str * d = (struct dm_str *) q->q_ptr;
        !           416: 
        !           417:                if ((iocp->ioc_cmd & DUMPIOC) == DUMPIOC) {
        !           418: 
        !           419:                        dumpioc (q, mp);
        !           420:                        return;
        !           421:                }
        !           422: 
        !           423:                cmn_err (CE_CONT, "^Co: M_IOCTL %x, cnt %d ",
        !           424:                         iocp->ioc_cmd, iocp->ioc_count);
        !           425: 
        !           426:                if ((d->dm_flags & D_VERB) != 0 && mp->b_cont)
        !           427:                        dumpshow (mp->b_cont, iocp->ioc_count);
        !           428: 
        !           429:                d->dm_dir = D_NONE;
        !           430: 
        !           431:        } else if (mp->b_datap->db_type == M_DATA)
        !           432:                dumpgather (q, mp, D_OUT);
        !           433:        else
        !           434:                dumpctl (q, mp, D_OUT);
        !           435: 
        !           436:        putnext (q, mp);
        !           437: }
        !           438: 
        !           439: 
        !           440: /*
        !           441:  * Read side put procedure, simply discriminates between upwards-bound control
        !           442:  * and data.
        !           443:  */
        !           444: 
        !           445: #if    __USE_PROTO__
        !           446: void dumprput (queue_t * q, mblk_t * mp)
        !           447: #else
        !           448: void
        !           449: dumprput (q, mp)
        !           450: queue_t              * q;
        !           451: mblk_t       * mp;
        !           452: #endif
        !           453: {
        !           454:        if (mp->b_datap->db_type == M_DATA)
        !           455:                dumpgather (q, mp, D_IN);
        !           456:        else
        !           457:                dumpctl (q, mp, D_IN);
        !           458: 
        !           459:        putnext (q, mp);
        !           460: }
        !           461: 

unix.superglobalmegacorp.com

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