129 lines
2.5 KiB
C
129 lines
2.5 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
/* Portions of this file are Copyright (C) 9front's team.
|
|
* See /doc/license/9front-mit for details about the licensing.
|
|
* See http://git.9front.org/plan9front/plan9front/HEAD/info.html for a list of authors.
|
|
*/
|
|
#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 = (Req **)&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=(Req **)(&(*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);
|
|
}
|
|
|