logd: missing klogd content
- regression in log_strtok_r (part deux) In commit
'logd: fix kernel logline stutter'
2c3b300fd8307e8da13608197d0a89bc613de5fb we introduced log_strtok_r.
as a replacement for strtok_r that dealt with a problem with
some kernel log messages. Fix is to refine definition of
is_timestamp to not match on patterns like [0], requiring
a single period. Another fix is to refine definition of
is_prio to properly escape non-digit content.
- Missing content because SYSLOG_ACTION_SIZE_BUFFER with added logging
is too short for full read of SYSLOG_ACTION_READ_ALL dropping
initial content. Add a margin for additional 1024 bytes.
- Absolute _first_ log entry has sequence number of 1, which is
specifically dropped, start sequence count at 1 rather than 0.
- Remove trailing space for efficiency.
- If tag exists but no content, trick into kernel logging.
Bug: 21851884
Change-Id: I0867a555a3bca09bbf18d18e75e41dffffe57a23
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 7d14648..d578c04 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -45,8 +45,8 @@
}
char c;
while ((c = *s++)) {
- if (!isdigit(c) && (c == '>')) {
- return s;
+ if (!isdigit(c)) {
+ return (c == '>') ? s : NULL;
}
}
return NULL;
@@ -65,17 +65,15 @@
while ((c = *s++)) {
if ((c == '.') && first_period) {
first_period = false;
- continue;
- }
- if (!isdigit(c) && (c == ']')) {
- return s;
+ } else if (!isdigit(c)) {
+ return ((c == ']') && !first_period && (*s == ' ')) ? s : NULL;
}
}
return NULL;
}
// Like strtok_r with "\r\n" except that we look for log signatures (regex)
-// \(\(<[0-9]+>\)\([[] *[0-9]+[]]\)\{0,1\}\|[[] *[0-9]+[]]\)
+// \(\(<[0-9]+>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] *[0-9]+[.][0-9]+[]] \)
// and split if we see a second one without a newline.
#define SIGNATURE_MASK 0xF0
@@ -547,10 +545,21 @@
}
}
size_t l = etag - tag;
+ // skip leading space
while (isspace(*buf)) {
++buf;
}
- size_t n = 1 + l + 1 + strlen(buf) + 1;
+ // truncate trailing space
+ size_t b = strlen(buf);
+ while (b && isspace(buf[b-1])) {
+ --b;
+ }
+ // trick ... allow tag with empty content to be logged. log() drops empty
+ if (!b && l) {
+ buf = " ";
+ b = 1;
+ }
+ size_t n = 1 + l + 1 + b + 1;
// Allocate a buffer to hold the interpreted log message
int rc = n;
@@ -572,7 +581,8 @@
++np;
// Copy main message to the remainder
- strcpy(np, buf);
+ strncpy(np, buf, b);
+ np[b] = '\0';
// Log message
rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr,