1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "../port/error.h" 7 8 static char Ebadlogctl[] = "unknown log ctl message"; 9 10 enum { 11 Nlog = 4*1024, 12 }; 13 14 void 15 logopen(Log *alog) 16 { 17 lock(alog); 18 if(waserror()){ 19 unlock(alog); 20 nexterror(); 21 } 22 if(alog->opens == 0){ 23 if(alog->buf == nil) 24 alog->buf = malloc(Nlog); 25 alog->rptr = alog->buf; 26 alog->end = alog->buf + Nlog; 27 } 28 alog->opens++; 29 unlock(alog); 30 poperror(); 31 } 32 33 void 34 logclose(Log *alog) 35 { 36 lock(alog); 37 if(waserror()){ 38 unlock(alog); 39 nexterror(); 40 } 41 alog->opens--; 42 if(alog->opens == 0){ 43 free(alog->buf); 44 alog->buf = nil; 45 } 46 unlock(alog); 47 poperror(); 48 } 49 50 static int 51 logready(void *a) 52 { 53 Log *alog = a; 54 55 return alog->len; 56 } 57 58 long 59 logread(Log *alog, void *a, ulong, long n) 60 { 61 int i, d; 62 char *p, *rptr; 63 64 qlock(&alog->readq); 65 if(waserror()){ 66 qunlock(&alog->readq); 67 nexterror(); 68 } 69 70 for(;;){ 71 lock(alog); 72 if(alog->len){ 73 if(n > alog->len) 74 n = alog->len; 75 d = 0; 76 rptr = alog->rptr; 77 alog->rptr += n; 78 if(alog->rptr >= alog->end){ 79 d = alog->rptr - alog->end; 80 alog->rptr = alog->buf + d; 81 } 82 alog->len -= n; 83 unlock(alog); 84 85 i = n-d; 86 p = a; 87 memmove(p, rptr, i); 88 memmove(p+i, alog->buf, d); 89 break; 90 } 91 else 92 unlock(alog); 93 94 sleep(&alog->readr, logready, alog); 95 } 96 97 qunlock(&alog->readq); 98 poperror(); 99 100 return n; 101 } 102 103 char* 104 logctl(Log *alog, int argc, char *argv[], Logflag *flags) 105 { 106 int i, set; 107 Logflag *fp; 108 109 if(argc < 2) 110 return Ebadlogctl; 111 112 if(strcmp("set", argv[0]) == 0) 113 set = 1; 114 else if(strcmp("clear", argv[0]) == 0) 115 set = 0; 116 else 117 return Ebadlogctl; 118 119 for(i = 1; i < argc; i++){ 120 for(fp = flags; fp->name; fp++) 121 if(strcmp(fp->name, argv[i]) == 0) 122 break; 123 if(fp->name == nil) 124 continue; 125 if(set) 126 alog->logmask |= fp->mask; 127 else 128 alog->logmask &= ~fp->mask; 129 } 130 131 return nil; 132 } 133 134 void 135 log(Log *alog, int mask, char *fmt, ...) 136 { 137 char buf[128], *t, *fp; 138 int i, n; 139 va_list arg; 140 141 if(!(alog->logmask & mask)) 142 return; 143 144 va_start(arg, fmt); 145 n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf; 146 va_end(arg); 147 148 if(alog->opens == 0) 149 return; 150 151 lock(alog); 152 i = alog->len + n - Nlog; 153 if(i > 0){ 154 alog->len -= i; 155 alog->rptr += i; 156 if(alog->rptr >= alog->end) 157 alog->rptr = alog->buf + (alog->rptr - alog->end); 158 } 159 t = alog->rptr + alog->len; 160 fp = buf; 161 alog->len += n; 162 while(n-- > 0){ 163 if(t >= alog->end) 164 t = alog->buf + (t - alog->end); 165 *t++ = *fp++; 166 } 167 unlock(alog); 168 169 wakeup(&alog->readr); 170 } 171