From: Lukas Fleischer <lfleischer@lfos.de>
To: git@vger.kernel.org
Cc: Nicolas Pitre <nico@fluxnic.net>, Johannes Sixt <j6t@kdbg.org>
Subject: [PATCH v2] Refactor recv_sideband()
Date: Tue, 14 Jun 2016 23:00:38 +0200 [thread overview]
Message-ID: <20160614210038.31465-1-lfleischer@lfos.de> (raw)
In-Reply-To: <20160613195224.13398-1-lfleischer@lfos.de>
Improve the readability of recv_sideband() significantly by replacing
fragile buffer manipulations with string buffers and more sophisticated
format strings. Note that each line is printed using a single write()
syscall to avoid garbled output when multiple processes write to stderr
in parallel, see 9ac13ec (atomic write for sideband remote messages,
2006-10-11) for details.
Also, reorganize the overall control flow, remove some superfluous
variables and replace a custom implementation of strpbrk() with a call
to the standard C library function.
Signed-off-by: Lukas Fleischer <lfleischer@lfos.de>
---
Now uses a single write() invocation per line. Thanks to Nicolas and
Junio for bringing 9ac13ec to my attention.
sideband.c | 97 +++++++++++++++++++++-----------------------------------------
1 file changed, 33 insertions(+), 64 deletions(-)
diff --git a/sideband.c b/sideband.c
index fde8adc..8340a1b 100644
--- a/sideband.c
+++ b/sideband.c
@@ -13,103 +13,72 @@
* the remote died unexpectedly. A flush() concludes the stream.
*/
-#define PREFIX "remote:"
+#define PREFIX "remote: "
#define ANSI_SUFFIX "\033[K"
#define DUMB_SUFFIX " "
-#define FIX_SIZE 10 /* large enough for any of the above */
-
int recv_sideband(const char *me, int in_stream, int out)
{
- unsigned pf = strlen(PREFIX);
- unsigned sf;
- char buf[LARGE_PACKET_MAX + 2*FIX_SIZE];
- char *suffix, *term;
- int skip_pf = 0;
+ const char *term, *suffix;
+ char buf[LARGE_PACKET_MAX + 1];
+ struct strbuf outbuf = STRBUF_INIT;
+ const char *b, *brk;
- memcpy(buf, PREFIX, pf);
+ strbuf_addf(&outbuf, "%s", PREFIX);
term = getenv("TERM");
if (isatty(2) && term && strcmp(term, "dumb"))
suffix = ANSI_SUFFIX;
else
suffix = DUMB_SUFFIX;
- sf = strlen(suffix);
while (1) {
int band, len;
- len = packet_read(in_stream, NULL, NULL, buf + pf, LARGE_PACKET_MAX, 0);
+ len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX, 0);
if (len == 0)
break;
if (len < 1) {
fprintf(stderr, "%s: protocol error: no band designator\n", me);
return SIDEBAND_PROTOCOL_ERROR;
}
- band = buf[pf] & 0xff;
+ band = buf[0] & 0xff;
+ buf[len] = '\0';
len--;
switch (band) {
case 3:
- buf[pf] = ' ';
- buf[pf+1+len] = '\0';
- fprintf(stderr, "%s\n", buf);
+ fprintf(stderr, "%s%s\n", PREFIX, buf + 1);
return SIDEBAND_REMOTE_ERROR;
case 2:
- buf[pf] = ' ';
- do {
- char *b = buf;
- int brk = 0;
-
- /*
- * If the last buffer didn't end with a line
- * break then we should not print a prefix
- * this time around.
- */
- if (skip_pf) {
- b += pf+1;
- } else {
- len += pf+1;
- brk += pf+1;
- }
+ b = buf + 1;
- /* Look for a line break. */
- for (;;) {
- brk++;
- if (brk > len) {
- brk = 0;
- break;
- }
- if (b[brk-1] == '\n' ||
- b[brk-1] == '\r')
- break;
- }
+ /*
+ * Append a suffix to each nonempty line to clear the
+ * end of the screen line.
+ */
+ while ((brk = strpbrk(b, "\n\r"))) {
+ int linelen = brk - b;
- /*
- * Let's insert a suffix to clear the end
- * of the screen line if a line break was
- * found. Also, if we don't skip the
- * prefix, then a non-empty string must be
- * present too.
- */
- if (brk > (skip_pf ? 0 : (pf+1 + 1))) {
- char save[FIX_SIZE];
- memcpy(save, b + brk, sf);
- b[brk + sf - 1] = b[brk - 1];
- memcpy(b + brk - 1, suffix, sf);
- fprintf(stderr, "%.*s", brk + sf, b);
- memcpy(b + brk, save, sf);
- len -= brk;
+ if (linelen > 0) {
+ strbuf_addf(&outbuf, "%.*s%s%c",
+ linelen, b, suffix, *brk);
} else {
- int l = brk ? brk : len;
- fprintf(stderr, "%.*s", l, b);
- len -= l;
+ strbuf_addf(&outbuf, "%c", *brk);
}
+ xwrite(STDERR_FILENO, outbuf.buf, outbuf.len);
+ strbuf_reset(&outbuf);
+ strbuf_addf(&outbuf, "%s", PREFIX);
+
+ b = brk + 1;
+ }
- skip_pf = !brk;
- memmove(buf + pf+1, b + brk, len);
- } while (len);
+ if (*b) {
+ xwrite(STDERR_FILENO, outbuf.buf, outbuf.len);
+ /* Incomplete line, skip the next prefix. */
+ strbuf_reset(&outbuf);
+ }
continue;
case 1:
- write_or_die(out, buf + pf+1, len);
+ write_or_die(out, buf + 1, len);
continue;
default:
fprintf(stderr, "%s: protocol error: bad band #%d\n",
--
2.8.3
next prev parent reply other threads:[~2016-06-14 21:00 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-13 19:52 [PATCH] Refactor recv_sideband() Lukas Fleischer
2016-06-13 21:07 ` Nicolas Pitre
2016-06-14 13:44 ` Johannes Schindelin
2016-06-14 15:04 ` Nicolas Pitre
2016-06-14 15:30 ` Johannes Schindelin
[not found] ` <Cq7rbYgOpb0CVCq7sbGmpL@videotron.ca>
2016-06-14 16:43 ` Nicolas Pitre
2016-06-14 17:09 ` Nicolas Pitre
[not found] ` <CsLdb3qLMBok7CsLebwX38@videotron.ca>
2016-06-14 17:55 ` Nicolas Pitre
2016-06-14 18:11 ` Junio C Hamano
2016-06-14 19:11 ` Lukas Fleischer
2016-06-14 19:16 ` Junio C Hamano
[not found] ` <Ct7VbfLfTHEALCt7Wbh8Xs@videotron.ca>
2016-06-14 20:10 ` Nicolas Pitre
2016-06-14 21:00 ` Lukas Fleischer [this message]
2016-06-14 21:11 ` [PATCH v2] " Lukas Fleischer
2016-06-14 21:25 ` Junio C Hamano
2016-06-15 3:44 ` Jeff King
[not found] ` <146597489449.32143.1327156804178869158@s-8d3a2dc3.on.site.uni-stuttgart.de>
2016-06-19 10:48 ` Lukas Fleischer
2016-06-24 15:31 ` Jeff King
2016-06-24 17:45 ` Johannes Schindelin
2016-06-24 18:14 ` Jeff King
2016-06-24 18:32 ` Junio C Hamano
2016-06-27 10:58 ` Lukas Fleischer
2016-06-27 15:54 ` Junio C Hamano
2016-06-27 16:16 ` Jeff King
2016-06-27 17:50 ` Junio C Hamano
2016-06-27 20:34 ` Lukas Fleischer
2016-06-27 20:47 ` Nicolas Pitre
2016-06-28 4:01 ` Lukas Fleischer
2016-06-28 5:20 ` Junio C Hamano
2016-06-28 10:04 ` Johannes Schindelin
2016-06-28 10:05 ` Johannes Schindelin
2016-06-28 15:13 ` Junio C Hamano
2016-06-28 16:21 ` Johannes Schindelin
2016-06-24 20:07 ` Dennis Kaarsemaker
2016-06-22 5:29 ` [PATCH v3] " Lukas Fleischer
2016-06-22 15:02 ` Nicolas Pitre
2016-06-22 22:47 ` Nicolas Pitre
2016-06-23 17:35 ` Lukas Fleischer
2016-06-23 18:59 ` Nicolas Pitre
2016-06-28 4:35 ` [PATCH v4] " Lukas Fleischer
2016-06-28 16:57 ` Junio C Hamano
2016-06-28 17:24 ` Junio C Hamano
2016-06-28 17:46 ` Nicolas Pitre
2016-06-28 18:13 ` Junio C Hamano
2016-06-28 18:28 ` Nicolas Pitre
2016-06-28 19:51 ` Junio C Hamano
2016-06-28 20:36 ` Nicolas Pitre
2016-06-28 21:09 ` Junio C Hamano
2016-06-28 21:44 ` Nicolas Pitre
2016-06-28 22:33 ` Junio C Hamano
2016-06-28 22:47 ` Junio C Hamano
2016-06-29 3:00 ` Junio C Hamano
2016-06-29 3:41 ` Nicolas Pitre
2016-06-29 2:02 ` Nicolas Pitre
2016-06-29 16:40 ` Junio C Hamano
2016-06-30 6:16 ` Lukas Fleischer
2016-07-01 20:01 ` Junio C Hamano
2016-07-05 20:35 ` Nicolas Pitre
2016-07-06 21:11 ` Junio C Hamano
2016-07-07 0:56 ` Nicolas Pitre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160614210038.31465-1-lfleischer@lfos.de \
--to=lfleischer@lfos.de \
--cc=git@vger.kernel.org \
--cc=j6t@kdbg.org \
--cc=nico@fluxnic.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).