summaryrefslogtreecommitdiff
path: root/sysklogd/klogd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-04 16:40:17 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-04 16:40:17 +0000
commit93d0776a96919a94fca51fe2cfd9530d8c9dcbb9 (patch)
treea9714be0d4c6b22c97c63db94b26e934a0338d06 /sysklogd/klogd.c
parentc2d5a27b622d5a048a3cf175e51f8b4b2b9e9757 (diff)
downloadbusybox-93d0776a96919a94fca51fe2cfd9530d8c9dcbb9.tar.gz
watchdog: WDIOC_SETTIMEOUT accepts seconds, not milliseconds
klogd: handle many lines at once, by Steve Bennett (steveb AT workware.net.au)
Diffstat (limited to 'sysklogd/klogd.c')
-rw-r--r--sysklogd/klogd.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index c4bbf1558..723ca8067 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -44,6 +44,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
int i = 0;
char *start;
int opt;
+ int used = 0;
opt = getopt32(argv, "c:n", &start);
if (opt & OPT_LEVEL) {
@@ -72,16 +73,15 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
- /* Note: this code does not detect incomplete messages
- * (messages not ending with '\n' or just when kernel
- * generates too many messages for us to keep up)
- * and will split them in two separate lines */
+ /* Initially null terminate the buffer in case of a very long line */
+ log_buffer[KLOGD_LOGBUF_SIZE - 1] = '\0';
+
while (1) {
int n;
int priority;
/* "2 -- Read from the log." */
- n = klogctl(2, log_buffer, KLOGD_LOGBUF_SIZE - 1);
+ n = klogctl(2, log_buffer + used, KLOGD_LOGBUF_SIZE-1 - used);
if (n < 0) {
if (errno == EINTR)
continue;
@@ -89,32 +89,47 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
errno);
break;
}
- log_buffer[n] = '\n';
- i = 0;
- while (i < n) {
+
+ /* klogctl buffer parsing modelled after code in dmesg.c */
+ start = &log_buffer[0];
+
+ /* Process each newline-terminated line in the buffer */
+ while (1) {
+ char *newline = strchr(start, '\n');
+
+ if (!newline) {
+ /* This line is incomplete... */
+ if (start != log_buffer) {
+ /* move it to the front of the buffer */
+ strcpy(log_buffer, start);
+ /* don't log it yet */
+ used = strlen(log_buffer);
+ break;
+ }
+ /* ...but buffer is full, so log it anyway */
+ used = 0;
+ } else {
+ *newline++ = '\0';
+ }
+
+ /* Extract the priority */
priority = LOG_INFO;
- start = &log_buffer[i];
- if (log_buffer[i] == '<') {
- i++;
- // kernel never ganerates multi-digit prios
- //priority = 0;
- //while (log_buffer[i] >= '0' && log_buffer[i] <= '9') {
- // priority = priority * 10 + (log_buffer[i] - '0');
- // i++;
- //}
- if (isdigit(log_buffer[i])) {
- priority = (log_buffer[i] - '0');
- i++;
+ if (*start == '<') {
+ start++;
+ if (*start) {
+ /* kernel never generates multi-digit prios */
+ priority = (*start - '0');
+ start++;
+ }
+ if (*start == '>') {
+ start++;
}
- if (log_buffer[i] == '>')
- i++;
- start = &log_buffer[i];
}
- while (log_buffer[i] != '\n')
- i++;
- log_buffer[i] = '\0';
- syslog(priority, "%s", start);
- i++;
+ if (*start)
+ syslog(priority, "%s", start);
+ if (!newline)
+ break;
+ start = newline;
}
}