diff options
Diffstat (limited to 'sideband.c')
-rw-r--r-- | sideband.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/sideband.c b/sideband.c index ef851113c4..85bddfdcd4 100644 --- a/sideband.c +++ b/sideband.c @@ -3,6 +3,7 @@ #include "config.h" #include "sideband.h" #include "help.h" +#include "pkt-line.h" struct keyword_entry { /* @@ -114,7 +115,8 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) #define ANSI_SUFFIX "\033[K" #define DUMB_SUFFIX " " -int demultiplex_sideband(const char *me, char *buf, int len, +int demultiplex_sideband(const char *me, int status, + char *buf, int len, int die_on_error, struct strbuf *scratch, enum sideband_type *sideband_type) @@ -130,24 +132,37 @@ int demultiplex_sideband(const char *me, char *buf, int len, suffix = DUMB_SUFFIX; } - if (len == 0) { - *sideband_type = SIDEBAND_FLUSH; - goto cleanup; - } - if (len < 1) { + if (status == PACKET_READ_EOF) { strbuf_addf(scratch, - "%s%s: protocol error: no band designator", + "%s%s: unexpected disconnect while reading sideband packet", scratch->len ? "\n" : "", me); *sideband_type = SIDEBAND_PROTOCOL_ERROR; goto cleanup; } + + if (len < 0) + BUG("negative length on non-eof packet read"); + + if (len == 0) { + if (status == PACKET_READ_NORMAL) { + strbuf_addf(scratch, + "%s%s: protocol error: missing sideband designator", + scratch->len ? "\n" : "", me); + *sideband_type = SIDEBAND_PROTOCOL_ERROR; + } else { + /* covers flush, delim, etc */ + *sideband_type = SIDEBAND_FLUSH; + } + goto cleanup; + } + band = buf[0] & 0xff; buf[len] = '\0'; len--; switch (band) { case 3: if (die_on_error) - die("remote error: %s", buf + 1); + die(_("remote error: %s"), buf + 1); strbuf_addf(scratch, "%s%s", scratch->len ? "\n" : "", DISPLAY_PREFIX); maybe_colorize_sideband(scratch, buf + 1, len); @@ -168,8 +183,31 @@ int demultiplex_sideband(const char *me, char *buf, int len, while ((brk = strpbrk(b, "\n\r"))) { int linelen = brk - b; + /* + * For message accross packet boundary, there would have + * a nonempty "scratch" buffer from last call of this + * function, and there may have a leading CR/LF in "buf". + * For this case we should add a clear-to-eol suffix to + * clean leftover letters we previously have written on + * the same line. + */ + if (scratch->len && !linelen) + strbuf_addstr(scratch, suffix); + if (!scratch->len) strbuf_addstr(scratch, DISPLAY_PREFIX); + + /* + * A use case that we should not add clear-to-eol suffix + * to empty lines: + * + * For progress reporting we may receive a bunch of + * percentage updates followed by '\r' to remain on the + * same line, and at the end receive a single '\n' to + * move to the next line. We should preserve the final + * status report line by not appending clear-to-eol + * suffix to this single line break. + */ if (linelen > 0) { maybe_colorize_sideband(scratch, b, linelen); strbuf_addstr(scratch, suffix); @@ -190,7 +228,7 @@ int demultiplex_sideband(const char *me, char *buf, int len, return 0; case 1: *sideband_type = SIDEBAND_PRIMARY; - break; + return 1; default: strbuf_addf(scratch, "%s%s: protocol error: bad band #%d", scratch->len ? "\n" : "", me, band); |