Plan 9 from Bell Labs’s /usr/web/sources/contrib/axel/8021x/v214/netlog.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].