URI:
       tlog.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tlog.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 }