FreeBSD/Linux Kernel Cross Reference
sys/port/log.c
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)
24 alog->buf = malloc(alog->nlog);
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 }
Cache object: 0661fcae9825d319ccd8b5457452174f
|