A következo lista egy "debug"
modul listáját tartalmazza. A modul
nem változtatja meg a rajta átmeno adatokat, csak egy hexa dumpot ír ki
róluk a konzolra. Ha valahol arra vagyunk kíváncsiak, hogy mi megy
keresztül egy streamen, akkor a kívánt helyre be kell illeszteni ezt a
modult, és futás közben elemezni kell az eredményeket.
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/cmn_err.h>
#define NULL ((char *)(0))
#define P_FELFELE 1
#define P_LEFELE 2
#define L_EGYSOR 16
extern nulldev();
static int dbugwrite(), dbugopen(), dbugclose();
static dumpmsg();
static struct module_info modinfo =
/* A stream queue jellemzoit irja le */
{ 0xa1, /* Modulazonosito szam */
"dbug", /* Modul neve */
0, /* Minimalis message-meret */
INFPSZ, /* Maximalis message-meret - INFPSZ=vegtelen */
0, 0 /* High; low water mark; 0=nincs ellenorzes */
};
static struct qinit dbugwinit =
/* "write" queue - lefele haladnak rajta az adatok */
{ dbuglput, /* Lefele meno adatok feldolgozasa */
nulldev, /* Service procedure */
dbugopen, /* open-nel ill. PUSH-nal meghivott rutin - comment */
dbugclose, /* utolso close-nal vagy pop-nal vegrehajtva - comment */
nulldev, /* admin bejegyzes (csak a 3bnet-hez kell) */
&modinfo, /* Modulinformacios struktura */
NULL /* Statisztikakat tartalmazo tablazat */
};
static struct qinit dbugrinit =
/* "read" queue - felfele haladnak rajta az adatok */
{ dbugfput, /* Felfele meno adatok feldolgozasa */
nulldev, /* Service proc. nincs */
dbugopen, /* open-nel, PUSH-nal meghivott rutin */
dbugclose, /* utolso close-nal vagy pop-nal meghivott r. */
nulldev, /* admin bejegyzes */
&modinfo, /* Modulinformacios struktura */
NULL /* Statisztikakat tartalmazo tablazat cime */
};
struct streamtab dbuginfo =
/* A kernel ez alapjan tud tajekozodni a driverben */
{ &dbugrinit, /* Read queue-rol informaciok */
&dbugwinit, /* Write queue-rol informaciok */
NULL, /* Multiplexer read queue */
NULL /* Multiplexer write queue */
};
static int dbugfput(q,mp) /* "put" rutin - felfele */
queue_t *q; /* Pointer a WRITE-queue-ra */
mblk_t *mp; /* Az adatra pointer */
{
dumpmsg(P_FELFELE,mp); /* Hexa dump */
putnext(q, mp); /* A megkapott uzenet tovabbitasa */
}
static int dbuglput(q,mp) /* "put" rutin - lefele */
queue_t *q; /* Pointer a WRITE-queue-ra */
mblk_t *mp; /* Az adatra pointer */
{
dumpmsg(P_LEFELE,mp); /* Hexa dump */
putnext(q, mp); /* A megkapott uzenet tovabbitasa */
}
static int dbugopen(q, dev, flag, sflag)
queue_t *q;
dev_t dev;
int flag,sflag;
{
return 0; /* Minden O.K. */
}
static int dbugclose(q)
queue_t *q;
{
return 0; /* Minden O.K. */
}
static dumpmsg(qdirection,mp)
int qdirection; /* Melyik iranyba megy az uzenet? */
mblk_t *mp; /* Az adatra pointer */
{ mblk_t *aktmess; /* Az aktualis uzenet */
register unsigned char *mitki; /* A kiirando karakterre pointer */
int kiirtak; /* Egy sorba mennyi karaktert irt ki */
aktmess=mp; /* Feltehetjuk, hogy nem NULLpointer */
if (qdirection == P_LEFELE) cmn_err(CE_NOTE,"LEFELE: ");
if (qdirection == P_FELFELE) cmn_err(CE_NOTE,"FELFELE: ");
kiirtak=0; /* Eddig a sorba egy karaktert sem raktunk ki */
while (aktmess != NULL) {
mitki=aktmess->b_rptr; /* Az adatterulet kezdete */
while (mitki < aktmess->b_wptr) { /* Adatterulet vege */
cmn_err(CE_CONT," 0x%b", *mitki);
kiirtak=kiirtak+1;
mitki=mitki+1;
if (kiirtak == L_EGYSOR) { /* Betelt egy sor */
kiirtak=0;
cmn_err(CE_CONT," \n");
}
}
aktmess=aktmess->b_cont; /* Folytatast is ... */
}
}