From c4ea27994bfa81e38dff9ccf9a92a33b5c612407 Mon Sep 17 00:00:00 2001 From: Jakub Horak Date: Thu, 11 Jan 2018 16:47:50 +0100 Subject: [PATCH] procd: Fix behavior when parsing long lines Processing of service stdout/stderr is silently stopped when long lines (>4096 bytes) are encountered. Moreover, when NUL byte (0) is received on input, the processing is stopped as well. When reading long lines procd waits until a newline character is received even though receive buffer is full. At that moment the file-descriptor is removed from epoll and communication stopson that descriptor stops. Similar thing happens with NUL byte, only that the newline is not found because "NUL" stops strchr() from processing further down the string. This patch corrects the behavior: long lines are broken into smaller ones with forced newline and NUL bytes are skipped when searching for a newline. Signed-off-by: Jakub Horak --- service/instance.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/service/instance.c b/service/instance.c index a968a0b..0293099 100644 --- a/service/instance.c +++ b/service/instance.c @@ -461,24 +461,34 @@ instance_stdio(struct ustream *s, int prio, struct service_instance *in) { char *newline, *str, *arg0, ident[32]; int len; + int buflen; arg0 = basename(blobmsg_data(blobmsg_data(in->command))); snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid); ulog_open(ULOG_SYSLOG, LOG_DAEMON, ident); do { - str = ustream_get_read_buf(s, NULL); + str = ustream_get_read_buf(s, &buflen); if (!str) break; - newline = strchr(str, '\n'); - if (!newline) - break; - - *newline = 0; + /* search for '\n', take into account NUL bytes */ + newline = memchr(str, '\n', buflen); + if (!newline) { + /* is there a room in buffer? */ + if (buflen < s->r.buffer_len) { + /* yes - bailout, newline may still come */ + break; + } else { + /* no - force newline */ + len = buflen; + } + } else { + *newline = 0; + len = newline + 1 - str; + } + /* "str" is NUL terminated by ustream_get_read_buf */ ulog(prio, "%s\n", str); - - len = newline + 1 - str; ustream_consume(s, len); } while (1); -- 2.7.4