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