log.c (1894B)
1 #include "a.h" 2 3 void 4 lbkick(Logbuf *lb) 5 { 6 char *s; 7 int n; 8 Req *r; 9 10 while(lb->wait && lb->rp != lb->wp){ 11 r = lb->wait; 12 lb->wait = r->aux; 13 if(lb->wait == nil) 14 lb->waitlast = &lb->wait; 15 r->aux = nil; 16 if(r->ifcall.count < 5){ 17 respond(r, "log read request count too short"); 18 continue; 19 } 20 s = lb->msg[lb->rp]; 21 lb->msg[lb->rp] = nil; 22 if(++lb->rp == nelem(lb->msg)) 23 lb->rp = 0; 24 n = r->ifcall.count; 25 if(n < strlen(s)+1+1){ 26 memmove(r->ofcall.data, s, n-5); 27 n -= 5; 28 r->ofcall.data[n] = '\0'; 29 /* look for first byte of UTF-8 sequence by skipping continuation bytes */ 30 while(n>0 && (r->ofcall.data[--n]&0xC0)==0x80) 31 ; 32 strcpy(r->ofcall.data+n, "...\n"); 33 }else{ 34 strcpy(r->ofcall.data, s); 35 strcat(r->ofcall.data, "\n"); 36 } 37 r->ofcall.count = strlen(r->ofcall.data); 38 free(s); 39 respond(r, nil); 40 } 41 } 42 43 void 44 lbread(Logbuf *lb, Req *r) 45 { 46 if(lb->waitlast == nil) 47 lb->waitlast = &lb->wait; 48 *lb->waitlast = r; 49 lb->waitlast = (Req**)(void*)&r->aux; 50 r->aux = nil; 51 lbkick(lb); 52 } 53 54 void 55 lbflush(Logbuf *lb, Req *r) 56 { 57 Req **l; 58 59 for(l=&lb->wait; *l; l=(Req**)(void*)&(*l)->aux){ 60 if(*l == r){ 61 *l = r->aux; 62 r->aux = nil; 63 if(*l == nil) 64 lb->waitlast = l; 65 respond(r, "interrupted"); 66 break; 67 } 68 } 69 } 70 71 void 72 lbappend(Logbuf *lb, char *fmt, ...) 73 { 74 va_list arg; 75 76 va_start(arg, fmt); 77 lbvappend(lb, fmt, arg); 78 va_end(arg); 79 } 80 81 void 82 lbvappend(Logbuf *lb, char *fmt, va_list arg) 83 { 84 char *s; 85 86 s = vsmprint(fmt, arg); 87 if(s == nil) 88 sysfatal("out of memory"); 89 if(lb->msg[lb->wp]) 90 free(lb->msg[lb->wp]); 91 lb->msg[lb->wp] = s; 92 if(++lb->wp == nelem(lb->msg)) 93 lb->wp = 0; 94 lbkick(lb); 95 } 96 97 Logbuf rpclogbuf; 98 99 void 100 rpclogread(Req *r) 101 { 102 lbread(&rpclogbuf, r); 103 } 104 105 void 106 rpclogflush(Req *r) 107 { 108 lbflush(&rpclogbuf, r); 109 } 110 111 void 112 rpclog(char *fmt, ...) 113 { 114 va_list arg; 115 116 va_start(arg, fmt); 117 lbvappend(&rpclogbuf, fmt, arg); 118 va_end(arg); 119 }