Annotation of coherent/b/STREAMS/conf/dump/src/dump.c, revision 1.1.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.