Blob


1 #include "a.h"
3 void
4 lbkick(Logbuf *lb)
5 {
6 char *s;
7 int n;
8 Req *r;
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 }
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 }
54 void
55 lbflush(Logbuf *lb, Req *r)
56 {
57 Req **l;
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 }
71 void
72 lbappend(Logbuf *lb, char *fmt, ...)
73 {
74 va_list arg;
76 va_start(arg, fmt);
77 lbvappend(lb, fmt, arg);
78 va_end(arg);
79 }
81 void
82 lbvappend(Logbuf *lb, char *fmt, va_list arg)
83 {
84 char *s;
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 }
97 Logbuf rpclogbuf;
99 void
100 rpclogread(Req *r)
102 lbread(&rpclogbuf, r);
105 void
106 rpclogflush(Req *r)
108 lbflush(&rpclogbuf, r);
111 void
112 rpclog(char *fmt, ...)
114 va_list arg;
116 va_start(arg, fmt);
117 lbvappend(&rpclogbuf, fmt, arg);
118 va_end(arg);