[systemd-devel] [PATCH] shared/log.c: log_struct_internal(): handle multiple lines
harald at redhat.com
harald at redhat.com
Wed Jun 26 06:06:37 PDT 2013
From: Harald Hoyer <harald at redhat.com>
Handle "VAR=line1\nline2\nline3" and split into
"VAR"
length
"line1\nline2\nline3"
"\n"
---
src/shared/log.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
diff --git a/src/shared/log.c b/src/shared/log.c
index 27317f7..2eb3d63 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -735,12 +735,13 @@ int log_struct_internal(
journal_fd >= 0) {
char header[LINE_MAX];
- struct iovec iovec[17] = {};
- unsigned n = 0, i;
+ struct iovec iovec[48] = {};
+ unsigned n = 0, i = 0;
struct msghdr mh = {
.msg_iov = iovec,
};
static const char nl = '\n';
+ uint64_t l[48] = {};
/* If the journal is available do structured logging */
log_do_header(header, sizeof(header), level,
@@ -748,9 +749,10 @@ int log_struct_internal(
IOVEC_SET_STRING(iovec[n++], header);
va_start(ap, format);
- while (format && n + 1 < ELEMENTSOF(iovec)) {
+ while (format && n + 5 < ELEMENTSOF(iovec)) {
char *buf;
va_list aq;
+ char *c, *nlp;
/* We need to copy the va_list structure,
* since vasprintf() leaves it afterwards at
@@ -768,7 +770,37 @@ int log_struct_internal(
* the next format string */
VA_FORMAT_ADVANCE(format, ap);
- IOVEC_SET_STRING(iovec[n++], buf);
+ IOVEC_SET_STRING(iovec[n], buf);
+
+ c = memchr(iovec[n].iov_base, '=', iovec[n].iov_len);
+ nlp = memchr(iovec[n].iov_base, nl, iovec[n].iov_len);
+ if (nlp && _likely_(nlp > c)) {
+ struct iovec iov;
+ iov.iov_base = iovec[n].iov_base;
+ iov.iov_len = iovec[n].iov_len;
+
+ /* Already includes a newline? Bummer, then
+ * let's write the variable name, then a
+ * newline, then the size (64bit LE), followed
+ * by the data and a final newline */
+ i = n;
+ iovec[n].iov_len = c - (char*) iov.iov_base;
+ n++;
+
+ iovec[n].iov_base = (char*) &nl;
+ iovec[n].iov_len = 1;
+ n++;
+
+ l[i] = htole64(iov.iov_len - (c - (char*) iov.iov_base) - 1);
+ iovec[n].iov_base = &l[i++];
+ iovec[n].iov_len = sizeof(uint64_t);
+ n++;
+
+ iovec[n].iov_base = c + 1;
+ iovec[n].iov_len = iov.iov_len - (c - (char*) iov.iov_base) - 1;
+ }
+
+ n++;
iovec[n].iov_base = (char*) &nl;
iovec[n].iov_len = 1;
@@ -786,8 +818,11 @@ int log_struct_internal(
finish:
va_end(ap);
- for (i = 1; i < n; i += 2)
+ for (i = 1; i < n; i += 2) {
free(iovec[i].iov_base);
+ if (l[i])
+ i += 3;
+ }
} else {
char buf[LINE_MAX];
--
1.8.3.1
More information about the systemd-devel
mailing list