ref: fe1eb39db7ae6904924f3ab1f6f9b34416f2eb1b
dir: /sys/src/cmd/auth/factotum/log.c/
#include "dat.h" static void logbufproc(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, "factotum: 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 logbufread(Logbuf *lb, Req *r) { qlock(lb); if(lb->waitlast == nil) lb->waitlast = &lb->wait; *(lb->waitlast) = r; lb->waitlast = &r->aux; r->aux = nil; logbufproc(lb); qunlock(lb); } void logbufflush(Logbuf *lb, Req *r) { Req **l; qlock(lb); for(l=&lb->wait; *l; l=&(*l)->aux){ if(*l == r){ *l = r->aux; if(*l == nil) lb->waitlast = l; r->aux = nil; respond(r, "interrupted"); break; } } qunlock(lb); } void logbufappend(Logbuf *lb, char *buf) { if(debug) fprint(2, "%s\n", buf); qlock(lb); if(lb->msg[lb->wp]) free(lb->msg[lb->wp]); lb->msg[lb->wp] = estrdup9p(buf); if(++lb->wp == nelem(lb->msg)) lb->wp = 0; logbufproc(lb); qunlock(lb); } Logbuf logbuf; void logread(Req *r) { logbufread(&logbuf, r); } void logflush(Req *r) { logbufflush(&logbuf, r); } void flog(char *fmt, ...) { char buf[1024]; va_list arg; va_start(arg, fmt); vseprint(buf, buf+sizeof buf, fmt, arg); va_end(arg); logbufappend(&logbuf, buf); }