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