#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)
{
memset(l, 0, sizeof(Netlog));
l->ping = chancreate(sizeof(int), 0);
l->name = strdup(name);
}
void
netlogopen(Netlog *l)
{
qlock(l);
if(l->opens == 0){
if(l->buf == nil)
l->buf = emalloc9p(Nlog);
l->rptr = l->buf;
l->end = l->buf + Nlog;
}
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, od;
char *p, *rptr, *eptr;
// syslog(0, logname, "netlogread %p n=%ld l->len=%d o=%lld l->o=%lld", l, n, l->len, o, l->offset);
qlock(l);
if (o + *off < l->offset) {
d = l->offset - o;
syslog(0, logname, "netlogread %s *off %d -> %d", l->name, *off, d);
*off = d;
}
if(l->len){
od = 0;
o += *off;
if (o > l->offset)
od = o - l->offset;
// syslog(0, logname, "netlogread %p: n=%ld od=%d off=%d l->len=%d l->b=%p l->r=%p l->e=%p", l, n, od, *off, l->len, l->buf, l->rptr, l->end);
if (od >= l->len) {
qunlock(l);
return 0;
}
if(n > l->len - od)
n = l->len - od;
if (n < 0)
logfatal(0, "netlogread n < 0");
else if (n == 0) {
qunlock(l);
return 0;
}
rptr = l->rptr;
rptr += od;
if (rptr >= l->end){
d = rptr - l->end;
rptr = l->buf + d;
}
d = 0;
eptr = rptr + n;
if(eptr >= l->end){
d = eptr - l->end;
eptr = l->buf + d;
}
USED(eptr);
i = n-d;
p = a;
// syslog(0, logname, "netlogread %p: n=%ld i=%d d=%d od=%d off=%d l->len=%d l->b=%p l->r=%p rptr=%p l->e=%p", l, n, i, d, od, *off, l->len, l->buf, l->rptr, rptr, l->end);
memmove(p, rptr, i);
memmove(p+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);
// syslog( 0, logname, "%s", buf);
pp = p - 1;
if (pp >= buf && *pp != '\n') {
*p = '\n';
p++;
}
n = p - buf;
i = l->len + n - Nlog;
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;
e = l->buf + d;
}
USED(e);
i = n-d;
fp = buf;
// syslog(0, logname, "netlogread %p: n=%ld i=%d d=%d od=%d off=%d l->len=%d l->b=%p l->r=%p rptr=%p l->e=%p", l, n, i, d, od, *off, l->len, l->buf, l->rptr, rptr, l->end);
memmove(t, fp, i);
memmove(l->buf, fp+i, d);
l->len += n;
#ifdef notdef
t = l->rptr + l->len;
fp = buf;
l->len += n;
while(n-- > 0){
if(t >= l->end)
t = l->buf + (t - l->end);
*t++ = *fp++;
}
#endif
qunlock(l);
// using nbsend works much better than send
// maybe because send forces to sync. why is this?
nbsend(l->ping, nil);
return n;
}
|