home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.internals:1630 comp.unix.programmer:4010
- Path: sparky!uunet!zephyr.ens.tek.com!psgrain!hippo!ucthpx!aim1!aim1!gram
- From: gram@aim1.aztec.co.za (Graham Wheeler)
- Newsgroups: comp.unix.internals,comp.unix.programmer
- Subject: STREAMS debug module
- Message-ID: <gram.712486053@aim1>
- Date: 30 Jul 92 08:47:33 GMT
- Organization: Aztec Information Management
- Lines: 397
-
- For those who are developing STREAMS applications and want to use the dump
- module for debugging, here it is. My STREAMS manual is riddled with typos,
- so I have fixed it up to the best of my ability. Also, I have the 3B2 manual
- but I'm using a 386, so I've changed a couple of things (added dumpdevflag,
- and made the extern declarations explicit; there is no /etc/master.d/dump
- file).
-
- Unfortunately, having created this module, I can't get autopush to accept
- it, so I don't know how much use it is going to be to me or anyone. But
- at least I may save some other people some time.
-
- autpush comes up with the message: `Invalid major device number or invalid
- module name or too many modules'. I have only the one module, my device
- number is valid (I am just replacing ldterm with dump over the same driver,
- and I never had problems with autopushing ldterm). If I do an ls -l on /dev,
- there I see:
-
- crw-rw-rw- 1 root root 77, 55 Jul 29 18:48 /dev/dump
-
- BTW, does anyone know why I am getting a minor dev number of 55, when my
- Node file is:
-
- dump dump c 0
-
- I have found this with other modules as well - the last entry always seems
- to bomb out. If, for example, I had:
-
- dump dump c 0
- dump dump c 1
- dump dump c 2
-
- I would get minor devs 0, 1 and 55.
-
- Why isn't anything in life simple? I've found it easier to implement a couple
- of OSI protocols in STREAMS than to get the configuration working properly, the
- dump module working, or a TCGETA ioctl to work (believe it or not).
-
- Here is the code. Sorry, I don't have shar, you'll have to cut it up yourselves.
-
- === dump.h ==================================================================
-
- /*
- * dump.h - header for DUMP module
- */
-
- #define DUMPIOC ('Q'<<8)
-
- #define DUMP_VERB (DUMPIOC | 1)
- #define DUMP_TERSE (DUMPIOC | 2)
-
- #define D_FREE 0
- #define D_USED 1
-
- #define D_OUT 1
- #define D_IN 2
-
- #define D_VERB 0x01
-
- struct dm_str {
- char dm_use;
- char dm_state;
- char dm_flags;
- };
-
- === dump.c ==========================================================
-
- #include "sys/types.h"
- #include "sys/stream.h"
- #include "sys/param.h"
- #include "sys/fcntl.h"
- #include "sys/cmn_err.h"
- #include "dump.h"
- #include "sys/termio.h"
-
- static struct module_info dumprinfo = { 0x6475, "dump", 0, INFPSZ, 0, 0 };
- static struct module_info dumpwinfo = { 0x6475, "dump", 0, INFPSZ, 0, 0 };
-
- static int dumpopen(), dumprput(), dumpwput(), dumpclose();
-
- static struct qinit rinit = {
- dumprput, NULL, dumpopen, dumpclose, NULL, &dumprinfo, NULL };
-
- static struct qinit winit = {
- dumpwput, NULL, NULL, NULL, NULL, &dumpwinfo, NULL };
-
- struct streamtab dumpinfo = { &rinit, &winit, NULL, NULL };
-
- int dm_ucnt=NUM_DUMP;
-
- struct dm_str dm_users[NUM_DUMP];
-
- int dumpdevflag = 0;
-
- /*
- * dumpopen
- */
-
- static int dumpopen(queue_t *q, dev_t *dev, int flag, int sflag) {
- register int i;
-
- if (q->q_ptr != NULL) {
- cmn_err(CE_CONT, "^DUMP: re-open slot %d\n",
- ((struct dm_str *)q->q_ptr - dm_users));
- if (flag & O_NDELAY)
- cmn_err(CE_CONT, "^DUMP: re-open: O_NDELAY set\n");
- return 0;
- }
- for (i=0; i<dm_ucnt; i++) {
- if (dm_users[i].dm_use == D_FREE) {
- dm_users[i].dm_use = D_USED;
- dm_users[i].dm_state = 0;
- dm_users[i].dm_flags = D_VERB;
- q->q_ptr = (caddr_t)&dm_users[i];
- if (flag & O_NDELAY)
- cmn_err(CE_CONT,"^DUMP: open: O_NDELAY set\n");
- return 0;
- }
- }
- return OPENFAIL;
- }
-
- /*
- * dumpclose
- */
-
- static int dumpclose(queue_t *q, int flag) {
- struct dm_str *d;
- d = (struct dm_str *)q->q_ptr;
- d->dm_use = D_FREE;
- d->dm_flags = 0;
- q->q_ptr = 0;
- WR(q)->q_ptr = 0;
- return 0;
- }
-
- static int dumpwput(queue_t *q, mblk_t *mp) {
- struct iocblk *iocp;
- struct dm_str *d;
-
- d = (struct dm_str *)q->q_ptr;
- if (mp->b_datap->db_type == M_IOCTL) {
- iocp = (struct iocblk *)mp->b_rptr;
- if ((iocp->ioc_cmd & DUMPIOC)==DUMPIOC) {
- dumpioc(q,mp);
- return 0;
- } else {
- cmn_err(CE_CONT,"^o: M_IOCTL %x, cnt %d ",
- iocp->ioc_cmd, iocp->ioc_count);
- if ((d->dm_flags & D_VERB) && mp->b_cont)
- dumpshow(mp->b_cont, iocp->ioc_cmd);
- d->dm_state = 0;
- putnext(q,mp);
- }
- } else if (mp->b_datap->db_type == M_DATA) {
- dumpgather(q,mp,D_OUT);
- putnext(q,mp);
- } else {
- dumpctl(q,mp,d,D_OUT);
- d->dm_state = 0;
- putnext(q,mp);
- }
- }
-
- /*
- * dumprput
- */
-
- static int dumprput(queue_t *q, mblk_t *mp) {
- struct dm_str *d;
-
- d = (struct dm_str *)q->q_ptr;
- if (mp->b_datap->db_type == M_DATA) {
- dumpgather(q,mp,D_IN);
- } else {
- dumpctl(q,mp,d,D_IN);
- d->dm_state = 0;
- }
- putnext(q,mp);
- }
-
- /*
- * dumpgather
- */
-
- dumpgather(queue_t *q, mblk_t *mp, int dir) {
- register struct dm_str *d;
- register int sx;
- register unsigned char *readp;
- register mblk_t *tmp;
- int counter;
- char junk[2];
-
- d = (struct dm_str *)q->q_ptr;
- if (d->dm_state != dir) {
- d->dm_state = dir;
- cmn_err(CE_CONT,"^%s",((dir==D_IN) ? "I" : "O" ));
- }
- if ((!mp->b_datap) ||
- ((mp->b_rptr == mp->b_wptr) && (mp->b_cont == NULL))) {
- cmn_err(CE_CONT,"^DUMP: 0 len data msg %s\n",
- (dir==D_OUT) ? "OUT":"IN");
- return;
- }
- cmn_err(CE_CONT,"^ {{");
- tmp = mp;
- counter = 0;
- sx = splstr();
- junk[1] = ' ';
- more:
- readp = tmp->b_rptr;
- while (readp < tmp->b_wptr) {
- if (d->dm_flags & D_VERB) {
- if ((*readp >= ' ') && (*readp <= '~') && !(*readp & 0x80)) {
- junk[0] = *readp;
- cmn_err(CE_CONT, "^ %s",junk);
- } else cmn_err(CE_CONT,"^ 0x%x", *readp);
- } else {
- ++counter;
- }
- ++readp;
- }
- if ((tmp->b_cont) && (tmp->b_datap->db_type == M_DATA)) {
- tmp = tmp->b_cont;
- goto more;
- }
- if (!(d->dm_flags & D_VERB))
- cmn_err(CE_CONT,"^%d ",counter);
- cmn_err(CE_CONT,"^}} ");
- if (tmp->b_cont && (tmp->b_datap->db_type != M_DATA))
- cmn_err(CE_CONT,"^DUMP: non-data b_cont\n");
- splx(sx);
- }
-
- /*
- * dumpioc
- */
-
- dumpioc(queue_t *q, mblk_t *mp) {
- register struct iocblk *iocp;
- register struct dm_str *d, *rst;
- d = (struct dm_str *)q->q_ptr;
- iocp = (struct iocblk *)mp->b_datap->db_base;
- cmn_err(CE_CONT,"^DUMP: own ioctl is ");
- switch (iocp->ioc_cmd) {
- case DUMP_VERB:
- d->dm_flags |= D_VERB;
- cmn_err(CE_CONT, "^DUMP_VERB\n");
- break;
- case DUMP_TERSE:
- d->dm_flags &= ~D_VERB;
- cmn_err(CE_CONT, "^DUMP_TERSE\n");
- break;
- default:
- mp->b_datap->db_type = M_IOCNAK;
- cmn_err(CE_CONT,"^UNKNOWN DUMP IOCTL x%x\n",iocp->ioc_cmd);
- qreply(q,mp);
- return;
- }
- mp->b_datap->db_type = M_IOCACK;
- iocp->ioc_count = 0;
- qreply(q,mp);
- }
-
- /*
- * dumpctl
- */
-
- dumpctl(queue_t *q, mblk_t *mp, struct dm_str *d, int dir) {
- cmn_err(CE_CONT,"^%s: M_",((dir==D_IN) ? "i":"o"));
- switch(mp->b_datap->db_type) {
- case M_DATA:
- cmn_err(CE_CONT,"^DATA");
- break;
- case M_READ:
- cmn_err(CE_CONT,"^READ");
- break;
- case M_IOCTL:
- cmn_err(CE_CONT,"^IOCTL");
- break;
- case M_IOCACK:
- cmn_err(CE_CONT,"^IOCACK");
- break;
- case M_IOCNAK:
- cmn_err(CE_CONT,"^IOCNAK");
- break;
- case M_IOCDATA:
- cmn_err(CE_CONT,"^IOCDATA");
- break;
- case M_CTL:
- cmn_err(CE_CONT,"^CTL");
- break;
- case M_PROTO:
- cmn_err(CE_CONT,"^PROTO");
- break;
- case M_PCPROTO:
- cmn_err(CE_CONT,"^PCPROTO");
- break;
- case M_BREAK:
- cmn_err(CE_CONT,"^BREAK");
- break;
- case M_DELAY:
- cmn_err(CE_CONT,"^DELAY");
- break;
- case M_PASSFP:
- cmn_err(CE_CONT,"^PASSFP");
- break;
- case M_SETOPTS:
- cmn_err(CE_CONT,"^SETOPTS");
- break;
- case M_SIG:
- cmn_err(CE_CONT,"^SIG (%d) ",(int)*mp->b_rptr);
- break;
- case M_ERROR:
- cmn_err(CE_CONT,"^ERROR");
- break;
- case M_HANGUP:
- cmn_err(CE_CONT,"^HANGUP");
- break;
- case M_FLUSH:
- cmn_err(CE_CONT,"^FLUSH");
- break;
- case M_PCSIG:
- cmn_err(CE_CONT,"^PCSIG (%d) ",(int)*mp->b_rptr);
- break;
- case M_COPYOUT:
- cmn_err(CE_CONT,"^COPYOUT");
- break;
- case M_COPYIN:
- cmn_err(CE_CONT,"^COPYIN");
- break;
- case M_START:
- cmn_err(CE_CONT,"^START");
- break;
- case M_STOP:
- cmn_err(CE_CONT,"^STOP");
- break;
- case M_STARTI:
- cmn_err(CE_CONT,"^STARTI");
- break;
- case M_STOPI:
- cmn_err(CE_CONT,"^STOPI");
- break;
- default:
- cmn_err(CE_CONT,"^Unknown!");
- }
- }
-
- /*
- * dumpshow
- */
-
- dumpshow(mblk_t *mp, int cmd) {
- int i;
- struct termio *t;
-
- switch (cmd) {
- case TCSETAF:
- cmn_err(CE_CONT,"^TCSETAF "); goto prtall;
- case TCSETA:
- cmn_err(CE_CONT,"^TCSETA "); goto prtall;
- case TCSETAW:
- cmn_err(CE_CONT,"^TCSETAW "); goto prtall;
- case TCGETA:
- cmn_err(CE_CONT,"^TCGETA "); goto prtall;
- prtall:
- t = (struct termio *) mp->b_rptr;
- cmn_err(CE_CONT,"^if = %x; of = %x; cf=%x; lf=%x\ncc=",
- t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);
- for (i=0;i<NCC;i++)
- cmn_err(CE_CONT,"^0x%x ",(int)t->c_cc[i]);
- cmn_err(CE_CONT,"^\n");
- break;
- default:
- return;
- }
- }
-
- === Node ==================================================================
-
- dump dump c 0
-
- === sdevice =================================================================
-
- dump Y 1 0 0 0 0 0 0 0
-
- === Master ==================================================================
-
- dump - ifSoc dump 0 0 1 1 -1
-
- =============================================================================
-
-
- --
- Graham Wheeler | "That which is weak conquers the strong,
- Software Systems Engineer/Student | that which is soft conquers the hard."
- Aztec Information Management/UCT | Lao Tzu - Tao Te Ching Ch. 78
- gram@aim1.aztec.co.za / gram@cs.uct.ac.za
-