|
|
1.1 ! root 1: /* ! 2: * stream tracer ! 3: */ ! 4: ! 5: #include "trc.h" ! 6: #if NTRC > 0 ! 7: #include "../h/param.h" ! 8: #include "../h/stream.h" ! 9: #include "../h/ioctl.h" ! 10: #include "../h/conf.h" ! 11: #include "../h/strace.h" ! 12: ! 13: ! 14: extern int nulldev(); ! 15: ! 16: struct trc trc[NTRC]; ! 17: ! 18: int trcclose(), /* queue close routine */ ! 19: trcopen(), /* queue open routine */ ! 20: trcput(); /* queue put routine */ ! 21: ! 22: static struct qinit rinit = { trcput, nulldev, trcopen, trcclose, 300, 0 }, ! 23: winit = { trcput, nulldev, trcopen, trcclose, 300, 200 }; ! 24: struct streamtab trcinfo = { &rinit, &winit }; ! 25: ! 26: ! 27: trcclose (q) ! 28: register struct queue *q; ! 29: { ! 30: register struct trc *tr = (struct trc *) q->ptr; ! 31: ! 32: trcupdate (q); ! 33: trcupdate (WR (q)); ! 34: tr->tr_state = 0; ! 35: printf ("%s: close\n", tr->tr_name); ! 36: return; ! 37: } ! 38: ! 39: ! 40: /* ! 41: * I/O control operations. ! 42: * Process request and return nonzero iff request is for us. ! 43: */ ! 44: ! 45: trcioctl (q, b) ! 46: register struct queue *q; ! 47: register struct block *b; ! 48: { ! 49: register struct trc *tr = (struct trc *) q->ptr; ! 50: register struct trcioc *ioc = (struct trcioc *) b->rptr; ! 51: ! 52: switch (ioc->command) { ! 53: ! 54: /* ! 55: * get name ! 56: */ ! 57: case TRCGNAME: ! 58: bcopy (tr->tr_name, ioc->arg.name, TR_NAME-1); ! 59: printf ("%s: get name %d\n", tr->tr_name, tr-trc); ! 60: b->wptr = b->rptr + sizeof (int) + TR_NAME - 1; ! 61: break; ! 62: ! 63: /* ! 64: * set name ! 65: */ ! 66: case TRCSNAME: ! 67: bcopy (ioc->arg.name, tr->tr_name, TR_NAME-1); ! 68: tr->tr_name[TR_NAME-1] = '\0'; ! 69: printf ("%s: set name %d\n", tr->tr_name, tr-trc); ! 70: b->wptr = b->rptr; ! 71: break; ! 72: ! 73: /* ! 74: * get block type trace mask ! 75: */ ! 76: case TRCGMASK: ! 77: ioc->arg.mask = tr->tr_mask; ! 78: printf ("%s: get mask 0x%x\n", tr->tr_name, tr->tr_mask); ! 79: b->wptr = b->rptr + 2 * sizeof (int); ! 80: break; ! 81: ! 82: /* ! 83: * set block type trace mask ! 84: */ ! 85: case TRCSMASK: ! 86: tr->tr_mask = ioc->arg.mask; ! 87: printf ("%s: set mask 0x%x\n", tr->tr_name, tr->tr_mask); ! 88: b->wptr = b->rptr; ! 89: break; ! 90: ! 91: default: ! 92: return (0); ! 93: } ! 94: ! 95: b->type = M_IOCACK; ! 96: qreply (q, b); ! 97: return (1); ! 98: } ! 99: ! 100: ! 101: /*ARGSUSED*/ ! 102: ! 103: int ! 104: trcopen (q, dev) ! 105: register struct queue *q; ! 106: int dev; ! 107: { ! 108: register struct trc *tr; ! 109: ! 110: if (q->ptr) ! 111: return (1); /* already attached */ ! 112: ! 113: for (tr = trc; tr->tr_state & TR_USE; tr++) ! 114: if (tr >= &trc[NTRC-1]) ! 115: return (0); ! 116: ! 117: WR (q)->ptr = q->ptr = (caddr_t) tr; ! 118: ! 119: tr->tr_state = TR_USE; ! 120: tr->tr_mask = ~0; /* trace all block types */ ! 121: bcopy ("trc", tr->tr_name, 4); ! 122: trcupdate (q); ! 123: trcupdate (WR (q)); ! 124: printf ("trc: open %d\n", tr-trc); ! 125: ! 126: return (1); ! 127: } ! 128: ! 129: ! 130: trcprb (b) ! 131: register struct block *b; ! 132: { ! 133: u_char buf[1+4+4*64]; /* 64 is max # bytes in a block */ ! 134: register u_char *nl, *s, *t, *u; ! 135: register int c; ! 136: ! 137: for (s = b->rptr, t = b->wptr, nl = u = buf; s < t; s++) { ! 138: if ((c = *s) & 0x80) { ! 139: *u++ = 'M'; ! 140: *u++ = '-'; ! 141: c &= ~0x80; ! 142: } ! 143: if (c == 0x7f) { ! 144: *u++ = '^'; ! 145: c = '?'; ! 146: } ! 147: else if (c < ' ') { ! 148: *u++ = '^'; ! 149: c += '@'; ! 150: } ! 151: *u++ = c; ! 152: if (u - nl > 64) ! 153: *(nl = u++) = '\n'; ! 154: } ! 155: ! 156: *u = '\0'; ! 157: printf ("%s", buf); ! 158: return; ! 159: } ! 160: ! 161: ! 162: #define trcpr(x) printf ("%s: %s %d bytes: %s", tr->tr_name, \ ! 163: rw, b->wptr-b->rptr, x) ! 164: ! 165: trcprint (q, b) ! 166: register struct queue *q; ! 167: register struct block *b; ! 168: { ! 169: register struct trc *tr = (struct trc *) q->ptr; ! 170: register char *rw = q->flag & QREADR ? "read" : "write"; ! 171: ! 172: switch (b->type) { ! 173: case M_ACK: ! 174: if (tr->tr_mask & TR_ACK) ! 175: trcpr ("M_ACK\n"); ! 176: break; ! 177: case M_BREAK: ! 178: if (tr->tr_mask & TR_BREAK) ! 179: trcpr ("M_BREAK\n"); ! 180: break; ! 181: case M_CLOSE: ! 182: if (tr->tr_mask & TR_CLOSE) ! 183: trcpr ("M_CLOSE\n"); ! 184: break; ! 185: case M_CTL: ! 186: if (tr->tr_mask & TR_CTL) ! 187: trcpr ("M_CTL\n"); ! 188: break; ! 189: case M_DATA: ! 190: if (tr->tr_mask & TR_DATA) ! 191: trcpr ("M_DATA: ``"), trcprb (b), printf ("''\n"); ! 192: break; ! 193: case M_DELAY: ! 194: if (tr->tr_mask & TR_DELAY) ! 195: trcpr ("M_DELAY"), printf (": %d\n", (int) *b->rptr); ! 196: break; ! 197: case M_DELIM: ! 198: if (tr->tr_mask & TR_DELIM) ! 199: trcpr ("M_DELIM\n"); ! 200: break; ! 201: case M_ECHO: ! 202: if (tr->tr_mask & TR_ECHO) ! 203: trcpr ("M_ECHO: ``"), trcprb (b), printf ("''\n"); ! 204: break; ! 205: case M_FLUSH: ! 206: if (tr->tr_mask & TR_FLUSH) ! 207: trcpr ("M_FLUSH\n"); ! 208: break; ! 209: case M_HANGUP: ! 210: if (tr->tr_mask & TR_HANGUP) ! 211: trcpr ("M_HANGUP\n"); ! 212: break; ! 213: case M_IOCACK: ! 214: if (tr->tr_mask & TR_IOCACK) ! 215: trcpr ("M_IOCACK\n"); ! 216: break; ! 217: case M_IOCNAK: ! 218: if (tr->tr_mask & TR_IOCNAK) ! 219: trcpr ("M_IOCNAK\n"); ! 220: break; ! 221: case M_IOCTL: ! 222: if (tr->tr_mask & TR_IOCTL) { ! 223: register int l = * (int *) b->rptr, h = l>>8; ! 224: ! 225: trcpr ("M_IOCTL"); ! 226: if (h >= ' ' && h < '\177') ! 227: printf (": ('%c'<<8)|%d\n", h, l & 0xff); ! 228: else printf (": 0x%x\n", l); ! 229: } ! 230: break; ! 231: case M_SIGNAL: ! 232: if (tr->tr_mask & TR_SIGNAL) ! 233: trcpr ("M_SIGNAL"), printf (": %d\n", (int) *b->rptr); ! 234: break; ! 235: case M_START: ! 236: if (tr->tr_mask & TR_START) ! 237: trcpr ("M_START\n"); ! 238: break; ! 239: case M_STOP: ! 240: if (tr->tr_mask & TR_STOP) ! 241: trcpr ("M_STOP\n"); ! 242: break; ! 243: default: ! 244: trcpr ("BAD BLOCK"), printf (": type %d\n", b->type); ! 245: break; ! 246: } ! 247: return; ! 248: } ! 249: ! 250: ! 251: /* ! 252: * Reader/Writer queue put routine. ! 253: */ ! 254: ! 255: trcput (q, b) ! 256: register struct queue *q; ! 257: register struct block *b; ! 258: { ! 259: register struct queue *qnext = q->next; ! 260: ! 261: if (b->type != M_IOCTL || !trcioctl (q, b)) { ! 262: trcprint (q, b); ! 263: (*qnext->qinfo->putp)(qnext, b); ! 264: } ! 265: trcupdate (q); ! 266: return; ! 267: } ! 268: ! 269: ! 270: trcupdate (q) ! 271: register struct queue *q; ! 272: { ! 273: register struct queue *qnext = q->next; ! 274: ! 275: q->flag |= qnext->flag & (QFULL|QWANTR) | backq(q)->flag & QDELIM; ! 276: qnext->flag |= q->flag & QWANTW; ! 277: q->count = qnext->count; ! 278: return; ! 279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.