diff options
author | Russ Cox <rsc@swtch.com> | 2008-08-03 07:42:27 -0700 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2008-08-03 07:42:27 -0700 |
commit | 18824b586835525594cde126fbc90b8281d5af8b (patch) | |
tree | e8b69c05eda4543b6d2f3d30777abe6109b48b7f /src/cmd/smugfs/log.c | |
parent | 3d36f4437348227c5bad62587dc12b5fd4a3e95e (diff) | |
download | plan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.gz plan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.bz2 plan9port-18824b586835525594cde126fbc90b8281d5af8b.zip |
smugfs(4): new program
Diffstat (limited to 'src/cmd/smugfs/log.c')
-rw-r--r-- | src/cmd/smugfs/log.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/cmd/smugfs/log.c b/src/cmd/smugfs/log.c new file mode 100644 index 00000000..5603211e --- /dev/null +++ b/src/cmd/smugfs/log.c @@ -0,0 +1,120 @@ +#include "a.h" + +void +lbkick(Logbuf *lb) +{ + char *s; + int n; + Req *r; + + while(lb->wait && lb->rp != lb->wp){ + r = lb->wait; + lb->wait = r->aux; + if(lb->wait == nil) + lb->waitlast = &lb->wait; + r->aux = nil; + if(r->ifcall.count < 5){ + respond(r, "log read request count too short"); + continue; + } + s = lb->msg[lb->rp]; + lb->msg[lb->rp] = nil; + if(++lb->rp == nelem(lb->msg)) + lb->rp = 0; + n = r->ifcall.count; + if(n < strlen(s)+1+1){ + memmove(r->ofcall.data, s, n-5); + n -= 5; + r->ofcall.data[n] = '\0'; + /* look for first byte of UTF-8 sequence by skipping continuation bytes */ + while(n>0 && (r->ofcall.data[--n]&0xC0)==0x80) + ; + strcpy(r->ofcall.data+n, "...\n"); + }else{ + strcpy(r->ofcall.data, s); + strcat(r->ofcall.data, "\n"); + } + r->ofcall.count = strlen(r->ofcall.data); + free(s); + respond(r, nil); + } +} + +void +lbread(Logbuf *lb, Req *r) +{ + if(lb->waitlast == nil) + lb->waitlast = &lb->wait; + *lb->waitlast = r; + lb->waitlast = (Req**)(void*)&r->aux; + r->aux = nil; + lbkick(lb); +} + +void +lbflush(Logbuf *lb, Req *r) +{ + Req **l; + + for(l=&lb->wait; *l; l=(Req**)(void*)&(*l)->aux){ + if(*l == r){ + *l = r->aux; + r->aux = nil; + if(*l == nil) + lb->waitlast = l; + respond(r, "interrupted"); + break; + } + } +} + +void +lbappend(Logbuf *lb, char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + lbvappend(lb, fmt, arg); + va_end(arg); +} + +void +lbvappend(Logbuf *lb, char *fmt, va_list arg) +{ + char *s; + + s = vsmprint(fmt, arg); + if(s == nil) + sysfatal("out of memory"); + if(lb->msg[lb->wp]) + free(lb->msg[lb->wp]); + lb->msg[lb->wp] = s; + if(++lb->wp == nelem(lb->msg)) + lb->wp = 0; + lbkick(lb); +} + +Logbuf rpclogbuf; + +void +rpclogread(Req *r) +{ + lbread(&rpclogbuf, r); +} + +void +rpclogflush(Req *r) +{ + lbflush(&rpclogbuf, r); +} + +void +rpclog(char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + lbvappend(&rpclogbuf, fmt, arg); + va_end(arg); +} + |