aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/smugfs/log.c
blob: 5e2f015a2909c9d599fce616801f21fec29c6c6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "a.h"

void
lbkick(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, "log 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
lbread(Logbuf *lb, Req *r)
{
	if(lb->waitlast == nil)
		lb->waitlast = &lb->wait;
	*lb->waitlast = r;
	lb->waitlast = (Req**)(void*)&r->aux;
	r->aux = nil;
	lbkick(lb);
}

void
lbflush(Logbuf *lb, Req *r)
{
	Req **l;

	for(l=&lb->wait; *l; l=(Req**)(void*)&(*l)->aux){
		if(*l == r){
			*l = r->aux;
			r->aux = nil;
			if(*l == nil)
				lb->waitlast = l;
			respond(r, "interrupted");
			break;
		}
	}
}

void
lbappend(Logbuf *lb, char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	lbvappend(lb, fmt, arg);
	va_end(arg);
}

void
lbvappend(Logbuf *lb, char *fmt, va_list arg)
{
	char *s;

	s = vsmprint(fmt, arg);
	if(s == nil)
		sysfatal("out of memory");
	if(lb->msg[lb->wp])
		free(lb->msg[lb->wp]);
	lb->msg[lb->wp] = s;
	if(++lb->wp == nelem(lb->msg))
		lb->wp = 0;
	lbkick(lb);
}

Logbuf rpclogbuf;

void
rpclogread(Req *r)
{
	lbread(&rpclogbuf, r);
}

void
rpclogflush(Req *r)
{
	lbflush(&rpclogbuf, r);
}

void
rpclog(char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	lbvappend(&rpclogbuf, fmt, arg);
	va_end(arg);
}