From: Martin Schwenke Date: Wed, 12 Jul 2023 00:39:06 +0000 (+1000) Subject: ctdb-tools: Improve printing of multi-line event script output X-Git-Tag: ldb-2.8.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7920d2ff627c6ef252e59b428236919ed0abb6ba;p=thirdparty%2Fsamba.git ctdb-tools: Improve printing of multi-line event script output Multi-line output currently prints like this: OUTPUT: aaa bbb ccc This is less beautiful than it could be. Instead, print multi-line output with no inlining and each line indented: OUTPUT: aaa bbb ccc However, continue to inline single line output: OUTPUT: foo Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/event/event_tool.c b/ctdb/event/event_tool.c index 5e94af1d9bc..e6d5261c217 100644 --- a/ctdb/event/event_tool.c +++ b/ctdb/event/event_tool.c @@ -199,8 +199,62 @@ static void print_status_one(struct ctdb_event_script *script) if ((script->result != 0 && script->result != -ENOEXEC) || script->output != NULL) { - printf(" OUTPUT: %s\n", - script->output == NULL ? "" : script->output); + /* Empty output is informative so always print it on failure */ + const char *t = script->output == NULL ? "" : script->output; + size_t len = strlen(t); + char output[len+1]; + size_t p; + char *t1, *t2; + + strlcpy(output, t, sizeof(output)); + + /* + * Strip trailing newlines, they are clutter and + * interfere with multi-line detection + */ + p = len - 1; + while (p >= 0 && output[p] == '\n') { + output[p] = '\0'; + p--; + } + + /* If the output is a single line then print it inline */ + t2 = strchr(output, '\n'); + if (t2 == NULL) { + printf(" OUTPUT: %s\n", output); + return; + } + + /* + * More than 1 line. Print a header and then each + * line, with suitable indent. There are more general + * ways to do this, but let's maintain intermediate + * blank lines (e.g. strv_split() loses blank lines). + */ + printf(" OUTPUT:\n"); + t1 = output; + do { + /* + * Points to newline character. t2 initially + * set non-NULL outside loop because this loop + * only covers multi-line output. + */ + *t2 = '\0'; + + + printf(" %s\n", t1); + t1 = t2 + 1; + + if (t1 >= output + len) { + break; + } + + /* strchrnul() would be awesome, but isn't portable */ + t2 = strchr(t1, '\n'); + if (t2 == NULL) { + t2 = output + len; + } + } while (true); } } diff --git a/ctdb/tests/UNIT/eventd/etc-ctdb/events/random/02.enabled.script b/ctdb/tests/UNIT/eventd/etc-ctdb/events/random/02.enabled.script index a59c58bf692..90df5218a9d 100755 --- a/ctdb/tests/UNIT/eventd/etc-ctdb/events/random/02.enabled.script +++ b/ctdb/tests/UNIT/eventd/etc-ctdb/events/random/02.enabled.script @@ -15,6 +15,15 @@ There are multiple output lines EOF exit 0 ;; +"verbosemultilinenonl") + cat <