aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/smugfs/log.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-08-03 07:42:27 -0700
committerRuss Cox <rsc@swtch.com>2008-08-03 07:42:27 -0700
commit18824b586835525594cde126fbc90b8281d5af8b (patch)
treee8b69c05eda4543b6d2f3d30777abe6109b48b7f /src/cmd/smugfs/log.c
parent3d36f4437348227c5bad62587dc12b5fd4a3e95e (diff)
downloadplan9port-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.c120
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);
+}
+