|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <sys/types.h> ! 3: #include <sys/stat.h> ! 4: ! 5: #define INTERVAL 60 ! 6: #define STRSIZE 64 ! 7: #define TABLESIZE 32 ! 8: #define PRINTFARGS fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 ! 9: #define IDLECYCLE 1000 ! 10: ! 11: static char *ControlFile = "TRACE"; ! 12: ! 13: static struct TraceRange { ! 14: char srcfile[STRSIZE]; ! 15: int from; ! 16: int to; ! 17: }; ! 18: static int TableSize; ! 19: static struct TraceRange RangeTable[TABLESIZE]; ! 20: static struct TraceRange Context[16]; ! 21: static int ContextIndex; ! 22: static Calls; ! 23: ! 24: static FILE *Tty; ! 25: static char Device[STRSIZE]; ! 26: ! 27: static void ifprintf( PRINTFARGS ) ! 28: { ! 29: if( Tty ){ ! 30: fprintf( Tty, PRINTFARGS ); ! 31: fflush( Tty ); ! 32: } ! 33: } ! 34: ! 35: #define SEMANTICS(text) { ifprintf( "Error: %s\n", text ); return 1; } ! 36: ! 37: static int RangeCmd( cmd ) ! 38: char *cmd; ! 39: { ! 40: struct TraceRange r, x; ! 41: ! 42: switch( sscanf( cmd, "range %s %d %d", r.srcfile, &r.from, &r.to ) ){ ! 43: case 2: r.to = r.from; ! 44: break; ! 45: case 3: break; ! 46: default: ! 47: return 0; ! 48: } ! 49: if( r.to < r.from ) { x = r; x.from = r.to; x.to = r.from; r = x; } ! 50: if( TableSize >= TABLESIZE ) SEMANTICS( "table overflow" ); ! 51: RangeTable[TableSize++] = r; ! 52: return 1; ! 53: } ! 54: ! 55: static int DeviceCmd( cmd ) ! 56: char *cmd; ! 57: { ! 58: if( sscanf( cmd, "device %s", Device ) != 1 ) return 0; ! 59: return 1; ! 60: } ! 61: ! 62: static void Commands(f) ! 63: FILE *f; ! 64: { ! 65: char cmd[STRSIZE]; ! 66: ! 67: TableSize = 0; ! 68: strcpy( Device, "/dev/null" ); ! 69: while( fgets( cmd, STRSIZE, f ) ){ ! 70: ifprintf( "%s", cmd ); ! 71: if( !RangeCmd(cmd) && ! 72: !DeviceCmd(cmd) ) ifprintf( "Syntax Error\n" ); ! 73: } ! 74: } ! 75: ! 76: static void Update() ! 77: { ! 78: static time_t modified; ! 79: FILE *f; ! 80: struct stat buf; ! 81: char shcmd[STRSIZE]; ! 82: ! 83: ifprintf( "trace 831120\n" ); ! 84: if( !(f = fopen( ControlFile, "r" ))) return; ! 85: fstat( fileno(f), &buf ); ! 86: if( buf.st_mtime != modified ) Commands(f); ! 87: modified = buf.st_mtime; ! 88: fclose(f); ! 89: if( !strcmp( Device, "/dev/null") ){ ! 90: if( Tty ) fclose( Tty ); ! 91: Tty = 0; ! 92: return; ! 93: } ! 94: if( f = fopen( Device, "w" ) ){ ! 95: if( Tty ) fclose( Tty ); ! 96: Tty = f; ! 97: } ! 98: else ifprintf( "Cannot open: %s\n", Device ); ! 99: } ! 100: ! 101: static void CheckTime(t) ! 102: long t; ! 103: { ! 104: static timestamp; ! 105: ! 106: if( t > timestamp+INTERVAL ){ ! 107: Update(); ! 108: timestamp = t; ! 109: } ! 110: } ! 111: ! 112: static int ContextSelected() ! 113: { ! 114: int i, line, from, to; ! 115: ! 116: for( i = 0; i < TableSize; ++i ) ! 117: if( !strcmp(Context[ContextIndex].srcfile, RangeTable[i].srcfile) ){ ! 118: line = Context[ContextIndex].from; ! 119: from = RangeTable[i].from; ! 120: to = RangeTable[i].to; ! 121: if( line>=from && line<=to ) return 1; ! 122: if( -line>=from && -line<=to ) return 0; ! 123: } ! 124: return 0; ! 125: } ! 126: ! 127: static TraceArgs( PRINTFARGS ) ! 128: { ! 129: char mmss[32]; ! 130: long time(), t = time(0L); ! 131: char *ctime(); ! 132: ! 133: --ContextIndex; ! 134: CheckTime(t); ! 135: if( !Tty || !ContextSelected() ) return 0; ! 136: strcpy( mmss, &ctime(&t)[14]); /* "Sun Sep 16 01:03:52 1973\n\0" */ ! 137: mmss[5] = '\0'; ! 138: fprintf(Tty, "%d %s %s:%d ", ! 139: Calls, mmss, Context[ContextIndex].srcfile, Context[ContextIndex].from); ! 140: fprintf( Tty, PRINTFARGS ); ! 141: fputc( '\n', Tty ); ! 142: fflush( Tty ); ! 143: return 1; ! 144: } ! 145: ! 146: typedef int (*PFI)(); ! 147: ! 148: static long *watchloc, watchval; ! 149: ! 150: PFI trace_fcn( srcfile, line ) ! 151: char *srcfile; ! 152: { ! 153: static idle; ! 154: ! 155: ++Calls; ! 156: if( !Tty && idle ){ ! 157: idle = (idle+1)%IDLECYCLE; ! 158: return 0; ! 159: } ! 160: if( watchloc && watchval!=*watchloc ){ ! 161: ifprintf(Tty, "!!!!!!! %s:%d *%d: %d -> %d\n", ! 162: srcfile, line, watchloc, watchval, *watchloc ); ! 163: watchval = *watchloc; ! 164: } ! 165: strncpy( Context[ContextIndex].srcfile, srcfile, STRSIZE ); ! 166: Context[ContextIndex].to = Context[ContextIndex].from = line; ! 167: ++ContextIndex; ! 168: return TraceArgs; ! 169: } ! 170: ! 171: watch(loc) ! 172: long *loc; ! 173: { ! 174: if( watchloc = loc ){ ! 175: watchval = *watchloc; ! 176: ifprintf(Tty, "watching *%d = %d\n", watchloc, watchval ); ! 177: } ! 178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.