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 (1885B)
       ---
            1 #include "std.h"
            2 #include "dat.h"
            3 
            4 void
            5 lbkick(Logbuf *lb)
            6 {
            7         char *s;
            8         int n;
            9         Req *r;
           10 
           11         while(lb->wait && lb->rp != lb->wp){
           12                 r = lb->wait;
           13                 lb->wait = r->aux;
           14                 if(lb->wait == nil)
           15                         lb->waitlast = &lb->wait;
           16                 r->aux = nil;
           17                 if(r->ifcall.count < 5){
           18                         respond(r, "factotum: read request count too short");
           19                         continue;
           20                 }
           21                 s = lb->msg[lb->rp];
           22                 lb->msg[lb->rp] = nil;
           23                 if(++lb->rp == nelem(lb->msg))
           24                         lb->rp = 0;
           25                 n = r->ifcall.count;
           26                 if(n < strlen(s)+1+1){
           27                         memmove(r->ofcall.data, s, n-5);
           28                         n -= 5;
           29                         r->ofcall.data[n] = '\0';
           30                         /* look for first byte of UTF-8 sequence by skipping continuation bytes */
           31                         while(n>0 && (r->ofcall.data[--n]&0xC0)==0x80)
           32                                 ;
           33                         strcpy(r->ofcall.data+n, "...\n");
           34                 }else{
           35                         strcpy(r->ofcall.data, s);
           36                         strcat(r->ofcall.data, "\n");
           37                 }
           38                 r->ofcall.count = strlen(r->ofcall.data);
           39                 free(s);
           40                 respond(r, nil);
           41         }
           42 }
           43 
           44 void
           45 lbread(Logbuf *lb, Req *r)
           46 {
           47         if(lb->waitlast == nil)
           48                 lb->waitlast = &lb->wait;
           49         *lb->waitlast = r;
           50         lb->waitlast = (Req**)(void*)&r->aux;
           51         r->aux = nil;
           52         lbkick(lb);
           53 }
           54 
           55 void
           56 lbflush(Logbuf *lb, Req *r)
           57 {
           58         Req **l;
           59 
           60         for(l=&lb->wait; *l; l=(Req**)(void*)&(*l)->aux){
           61                 if(*l == r){
           62                         *l = r->aux;
           63                         r->aux = nil;
           64                         if(*l == nil)
           65                                 lb->waitlast = l;
           66                         closereq(r);
           67                         break;
           68                 }
           69         }
           70 }
           71 
           72 void
           73 lbappend(Logbuf *lb, char *fmt, ...)
           74 {
           75         va_list arg;
           76 
           77         va_start(arg, fmt);
           78         lbvappend(lb, fmt, arg);
           79         va_end(arg);
           80 }
           81 
           82 void
           83 lbvappend(Logbuf *lb, char *fmt, va_list arg)
           84 {
           85         char *s;
           86 
           87         s = vsmprint(fmt, arg);
           88         if(s == nil)
           89                 sysfatal("out of memory");
           90         if(lb->msg[lb->wp])
           91                 free(lb->msg[lb->wp]);
           92         lb->msg[lb->wp] = s;
           93         if(++lb->wp == nelem(lb->msg))
           94                 lb->wp = 0;
           95         lbkick(lb);
           96 }
           97 
           98 Logbuf logbuf;
           99 
          100 void
          101 logread(Req *r)
          102 {
          103         lbread(&logbuf, r);
          104 }
          105 
          106 void
          107 logflush(Req *r)
          108 {
          109         lbflush(&logbuf, r);
          110 }
          111 
          112 void
          113 flog(char *fmt, ...)
          114 {
          115         va_list arg;
          116 
          117         va_start(arg, fmt);
          118         lbvappend(&logbuf, fmt, arg);
          119         va_end(arg);
          120 }