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