From 93d0776a96919a94fca51fe2cfd9530d8c9dcbb9 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 4 Oct 2008 16:40:17 +0000 Subject: [PATCH] watchdog: WDIOC_SETTIMEOUT accepts seconds, not milliseconds klogd: handle many lines at once, by Steve Bennett (steveb AT workware.net.au) --- miscutils/watchdog.c | 2 ++ sysklogd/klogd.c | 71 +++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index 9bcd4b874..75a399f24 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c @@ -55,6 +55,8 @@ int watchdog_main(int argc, char **argv) /* Use known fd # - avoid needing global 'int fd' */ xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); + /* WDIOC_SETTIMEOUT takes seconds, not milliseconds */ + htimer_duration = htimer_duration / 1000; ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration); #if 0 ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration); 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; } } -- 2.25.1