This source file includes following definitions.
- sys_syslog
- printk
- register_console
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <stdarg.h>
15
16 #include <asm/segment.h>
17 #include <asm/system.h>
18
19 #include <linux/errno.h>
20 #include <linux/sched.h>
21 #include <linux/kernel.h>
22 #include <linux/mm.h>
23
24 #define LOG_BUF_LEN 4096
25
26 static char buf[1024];
27
28 extern void console_print(const char *);
29
30
31 #define DEFAULT_MESSAGE_LOGLEVEL 5
32
33
34 #define MINIMUM_CONSOLE_LOGLEVEL 6
35 #define DEFAULT_CONSOLE_LOGLEVEL 6
36
37 unsigned long log_size = 0;
38 struct wait_queue * log_wait = NULL;
39 int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
40
41 static void (*console_print_proc)(const char *) = 0;
42 static char log_buf[LOG_BUF_LEN];
43 static unsigned long log_start = 0;
44 static unsigned long logged_chars = 0;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 asmlinkage int sys_syslog(int type, char * buf, int len)
60 {
61 unsigned long i, j, count;
62 int do_clear = 0;
63 char c;
64 int error;
65
66 if ((type != 3) && !suser())
67 return -EPERM;
68 switch (type) {
69 case 0:
70 return 0;
71 case 1:
72 return 0;
73 case 2:
74 if (!buf || len < 0)
75 return -EINVAL;
76 if (!len)
77 return 0;
78 error = verify_area(VERIFY_WRITE,buf,len);
79 if (error)
80 return error;
81 cli();
82 while (!log_size) {
83 if (current->signal & ~current->blocked) {
84 sti();
85 return -ERESTARTSYS;
86 }
87 interruptible_sleep_on(&log_wait);
88 }
89 i = 0;
90 while (log_size && i < len) {
91 c = *((char *) log_buf+log_start);
92 log_start++;
93 log_size--;
94 log_start &= LOG_BUF_LEN-1;
95 sti();
96 put_user(c,buf);
97 buf++;
98 i++;
99 cli();
100 }
101 sti();
102 return i;
103 case 4:
104 do_clear = 1;
105
106 case 3:
107 if (!buf || len < 0)
108 return -EINVAL;
109 if (!len)
110 return 0;
111 error = verify_area(VERIFY_WRITE,buf,len);
112 if (error)
113 return error;
114 count = len;
115 if (count > LOG_BUF_LEN)
116 count = LOG_BUF_LEN;
117 if (count > logged_chars)
118 count = logged_chars;
119 j = log_start + log_size - count;
120 for (i = 0; i < count; i++) {
121 c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
122 put_user(c, buf++);
123 }
124 if (do_clear)
125 logged_chars = 0;
126 return i;
127 case 5:
128 logged_chars = 0;
129 return 0;
130 case 6:
131 console_loglevel = MINIMUM_CONSOLE_LOGLEVEL;
132 return 0;
133 case 7:
134 console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
135 return 0;
136 case 8:
137 if (len < 1 || len > 8)
138 return -EINVAL;
139 if (len < MINIMUM_CONSOLE_LOGLEVEL)
140 len = MINIMUM_CONSOLE_LOGLEVEL;
141 console_loglevel = len;
142 return 0;
143 }
144 return -EINVAL;
145 }
146
147
148 asmlinkage int printk(const char *fmt, ...)
149 {
150 va_list args;
151 int i;
152 char *msg, *p, *buf_end;
153 static char msg_level = -1;
154 long flags;
155
156 save_flags(flags);
157 cli();
158 va_start(args, fmt);
159 i = vsprintf(buf + 3, fmt, args);
160 buf_end = buf + 3 + i;
161 va_end(args);
162 for (p = buf + 3; p < buf_end; p++) {
163 msg = p;
164 if (msg_level < 0) {
165 if (
166 p[0] != '<' ||
167 p[1] < '0' ||
168 p[1] > '7' ||
169 p[2] != '>'
170 ) {
171 p -= 3;
172 p[0] = '<';
173 p[1] = DEFAULT_MESSAGE_LOGLEVEL + '0';
174 p[2] = '>';
175 } else
176 msg += 3;
177 msg_level = p[1] - '0';
178 }
179 for (; p < buf_end; p++) {
180 log_buf[(log_start+log_size) & (LOG_BUF_LEN-1)] = *p;
181 if (log_size < LOG_BUF_LEN)
182 log_size++;
183 else {
184 log_start++;
185 log_start &= LOG_BUF_LEN-1;
186 }
187 logged_chars++;
188 if (*p == '\n')
189 break;
190 }
191 if (msg_level < console_loglevel && console_print_proc) {
192 char tmp = p[1];
193 p[1] = '\0';
194 (*console_print_proc)(msg);
195 p[1] = tmp;
196 }
197 if (*p == '\n')
198 msg_level = -1;
199 }
200 restore_flags(flags);
201 wake_up_interruptible(&log_wait);
202 return i;
203 }
204
205
206
207
208
209
210
211 void register_console(void (*proc)(const char *))
212 {
213 int i,j;
214 int p = log_start;
215 char buf[16];
216 char msg_level = -1;
217 char *q;
218
219 console_print_proc = proc;
220
221 for (i=0,j=0; i < log_size; i++) {
222 buf[j++] = log_buf[p];
223 p++; p &= LOG_BUF_LEN-1;
224 if (buf[j-1] != '\n' && i < log_size - 1 && j < sizeof(buf)-1)
225 continue;
226 buf[j] = 0;
227 q = buf;
228 if (msg_level < 0) {
229 msg_level = buf[1] - '0';
230 q = buf + 3;
231 }
232 if (msg_level < console_loglevel)
233 (*proc)(q);
234 if (buf[j-1] == '\n')
235 msg_level = -1;
236 j = 0;
237 }
238 }