Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "../port/error.h"
7
 
8
static char Ebadlogctl[] = "unknown log ctl message";
9
 
10
void
11
logopen(Log *alog)
12
{
13
	lock(alog);
14
	if(waserror()){
15
		unlock(alog);
16
		nexterror();
17
	}
18
	if(alog->opens == 0){
19
		if(alog->nlog == 0)
20
			alog->nlog = 4*1024;
21
		if(alog->minread == 0)
22
			alog->minread = 1;
23
		if(alog->buf == nil && (alog->buf = malloc(alog->nlog)) == nil)
24
			error(Enomem);
25
		alog->rptr = alog->buf;
26
		alog->end = alog->buf + alog->nlog;
27
		alog->len = 0;
28
	}
29
	alog->opens++;
30
	unlock(alog);
31
	poperror();
32
}
33
 
34
void
35
logclose(Log *alog)
36
{
37
	lock(alog);
38
	alog->opens--;
39
	if(alog->opens == 0){
40
		free(alog->buf);
41
		alog->buf = nil;
42
	}
43
	unlock(alog);
44
}
45
 
46
static int
47
logready(void *a)
48
{
49
	Log *alog = a;
50
 
51
	return alog->len >= alog->minread;
52
}
53
 
54
long
55
logread(Log *alog, void *a, ulong, long n)
56
{
57
	int i, d;
58
	char *p, *rptr;
59
 
60
	qlock(&alog->readq);
61
	if(waserror()){
62
		qunlock(&alog->readq);
63
		nexterror();
64
	}
65
 
66
	for(;;){
67
		lock(alog);
68
		if(alog->len >= alog->minread || alog->len >= n){
69
			if(n > alog->len)
70
				n = alog->len;
71
			d = 0;
72
			rptr = alog->rptr;
73
			alog->rptr += n;
74
			if(alog->rptr >= alog->end){
75
				d = alog->rptr - alog->end;
76
				alog->rptr = alog->buf + d;
77
			}
78
			alog->len -= n;
79
			unlock(alog);
80
 
81
			i = n-d;
82
			p = a;
83
			memmove(p, rptr, i);
84
			memmove(p+i, alog->buf, d);
85
			break;
86
		}
87
		else
88
			unlock(alog);
89
 
90
		sleep(&alog->readr, logready, alog);
91
	}
92
 
93
	qunlock(&alog->readq);
94
	poperror();
95
 
96
	return n;
97
}
98
 
99
char*
100
logctl(Log *alog, int argc, char *argv[], Logflag *flags)
101
{
102
	int i, set;
103
	Logflag *fp;
104
 
105
	if(argc < 2)
106
		return Ebadlogctl;
107
 
108
	if(strcmp("set", argv[0]) == 0)
109
		set = 1;
110
	else if(strcmp("clear", argv[0]) == 0)
111
		set = 0;
112
	else
113
		return Ebadlogctl;
114
 
115
	for(i = 1; i < argc; i++){
116
		for(fp = flags; fp->name; fp++)
117
			if(strcmp(fp->name, argv[i]) == 0)
118
				break;
119
		if(fp->name == nil)
120
			continue;
121
		if(set)
122
			alog->logmask |= fp->mask;
123
		else
124
			alog->logmask &= ~fp->mask;
125
	}
126
 
127
	return nil;
128
}
129
 
130
void
131
logn(Log *alog, int mask, void *buf, int n)
132
{
133
	char *fp, *t;
134
	int dowake, i;
135
 
136
	if(!(alog->logmask & mask))
137
		return;
138
 
139
	if(alog->opens == 0)
140
		return;
141
 
142
	if(n > alog->nlog)
143
		return;
144
 
145
	lock(alog);
146
	i = alog->len + n - alog->nlog;
147
	if(i > 0){
148
		alog->len -= i;
149
		alog->rptr += i;
150
		if(alog->rptr >= alog->end)
151
			alog->rptr = alog->buf + (alog->rptr - alog->end);
152
	}
153
	t = alog->rptr + alog->len;
154
	fp = buf;
155
	alog->len += n;
156
	while(n-- > 0){
157
		if(t >= alog->end)
158
			t = alog->buf + (t - alog->end);
159
		*t++ = *fp++;
160
	}
161
	dowake = alog->len >= alog->minread;
162
	unlock(alog);
163
 
164
	if(dowake)
165
		wakeup(&alog->readr);
166
}
167
 
168
void
169
log(Log *alog, int mask, char *fmt, ...)
170
{
171
	int n;
172
	va_list arg;
173
	char buf[128];
174
 
175
	if(!(alog->logmask & mask))
176
		return;
177
 
178
	if(alog->opens == 0)
179
		return;
180
 
181
	va_start(arg, fmt);
182
	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
183
	va_end(arg);
184
 
185
	logn(alog, mask, buf, n);
186
}