#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "dat.h"
#include "fns.h"
void
netloginit(Netlog *l, char *name, int size)
{
memset(l, 0, sizeof(Netlog));
l->ping = chancreate(sizeof(int), 0);
l->name = estrdup9p(name);
if (size <= 0)
size = Nlog;
l->size = size;
}
void
netlogopen(Netlog *l)
{
qlock(l);
if(l->opens == 0){
if(l->buf == nil)
l->buf = emalloc9p(l->size);
l->rptr = l->buf;
l->end = l->buf + l->size;
}
l->opens++;
qunlock(l);
}
void
netlogclose(Netlog *l)
{
qlock(l);
l->opens--;
if(l->opens == 0){
free(l->buf);
l->buf = nil;
l->len = 0;
}
qunlock(l);
}
long
netlogread(Netlog *l, void *a, long n, vlong o, int *off)
{
int i, d;
char *t, *fp, *e;
qlock(l);
if (o + *off < l->offset) {
d = l->offset - (o + *off);
*off = l->offset - o;
syslog(0, logname, "netlogread %s skip %d offset -> %d", l->name, d, *off);
}
if(l->len){
o += *off;
o -= l->offset;
if (o >= l->len) {
qunlock(l);
return 0;
}
if(n > l->len - o)
n = l->len - o;
if (n < 0)
logfatal(0, "netlogread n < 0 (n==%ld)", n);
else if (n == 0) {
qunlock(l);
return 0;
}
fp = l->rptr + o;
if (fp >= l->end){
d = fp - l->end;
fp = l->buf + d;
}
d = 0;
e = fp + n;
if(e >= l->end)
d = e - l->end;
i = n-d;
t = a;
memmove(t, fp, i);
memmove(t+i, l->buf, d);
} else
n = 0;
qunlock(l);
return n;
}
static char buf[Nlog];
int
netlog(Netlog *l, char *fmt, va_list arg)
{
vlong ns;
char *t, *fp;
char *ctim, *p, *pp, *e;
int i, n, d;
if (l->opens == 0)
return 0;
qlock(l);
ns = nsec();
ctim = nsctime(ns);
p = buf + snprint(buf, sizeof(buf)-1, "%s ", ctim);
p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
pp = p - 1;
if (pp >= buf && *pp != '\n') {
*p = '\n';
p++;
}
n = p - buf;
if (n > l->size){
d = n - l->size;
syslog(0, logname, "netlog %s n=%d > size=%d : discard %d", l->name, n, l->size, d);
n = l->size;
}
i = l->len + n - l->size;
if(i > 0){
l->offset += i;
l->len -= i;
l->rptr += i;
if(l->rptr >= l->end)
l->rptr = l->buf + (l->rptr - l->end);
}
t = l->rptr + l->len;
if (t >= l->end){
d = t - l->end;
t = l->buf + d;
}
d = 0;
e = t + n;
if(e >= l->end)
d = e - l->end;
i = n-d;
fp = buf;
memmove(t, fp, i);
memmove(l->buf, fp+i, d);
l->len += n;
qunlock(l);
// using nbsend works much better than send
// maybe because send forces to sync. why is this?
nbsend(l->ping, nil);
return n;
}
|