Skip to content

Commit 5e5be9e

Browse files
lfosgitster
authored andcommitted
sideband.c: refactor recv_sideband()
We used character buffer manipulations to split messages from the sideband at line breaks and insert "remote: " at the beginning of each line, using the packet size to determine the end of a message. However, since it is safe to assume that diagnostic messages from the sideband never contain NUL characters, we can also NUL-terminate the buffer, use strpbrk() for splitting lines and use format strings to insert the prefix, to make the code easier to read and maintain. A strbuf is used for accumulating the output which is then printed using a single write(2) call to ensure the atomicity of the output. See 9ac13ec (atomic write for sideband remote messages, 2006-10-11) for details. Helped-by: Jeff King <[email protected]> Helped-by: Junio C Hamano <[email protected]> Helped-by: Nicolas Pitre <[email protected]> Signed-off-by: Lukas Fleischer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7654286 commit 5e5be9e

File tree

1 file changed

+58
-74
lines changed

1 file changed

+58
-74
lines changed

sideband.c

Lines changed: 58 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -13,111 +13,95 @@
1313
* the remote died unexpectedly. A flush() concludes the stream.
1414
*/
1515

16-
#define PREFIX "remote:"
16+
#define PREFIX "remote: "
1717

1818
#define ANSI_SUFFIX "\033[K"
1919
#define DUMB_SUFFIX " "
2020

21-
#define FIX_SIZE 10 /* large enough for any of the above */
22-
2321
int recv_sideband(const char *me, int in_stream, int out)
2422
{
25-
unsigned pf = strlen(PREFIX);
26-
unsigned sf;
27-
char buf[LARGE_PACKET_MAX + 2*FIX_SIZE];
28-
char *suffix, *term;
29-
int skip_pf = 0;
23+
const char *term, *suffix;
24+
char buf[LARGE_PACKET_MAX + 1];
25+
struct strbuf outbuf = STRBUF_INIT;
26+
int retval = 0;
3027

31-
memcpy(buf, PREFIX, pf);
3228
term = getenv("TERM");
3329
if (isatty(2) && term && strcmp(term, "dumb"))
3430
suffix = ANSI_SUFFIX;
3531
else
3632
suffix = DUMB_SUFFIX;
37-
sf = strlen(suffix);
3833

39-
while (1) {
34+
while (!retval) {
35+
const char *b, *brk;
4036
int band, len;
41-
len = packet_read(in_stream, NULL, NULL, buf + pf, LARGE_PACKET_MAX, 0);
37+
len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX, 0);
4238
if (len == 0)
4339
break;
4440
if (len < 1) {
45-
fprintf(stderr, "%s: protocol error: no band designator\n", me);
46-
return SIDEBAND_PROTOCOL_ERROR;
41+
strbuf_addf(&outbuf,
42+
"%s%s: protocol error: no band designator",
43+
outbuf.len ? "\n" : "", me);
44+
retval = SIDEBAND_PROTOCOL_ERROR;
45+
break;
4746
}
48-
band = buf[pf] & 0xff;
47+
band = buf[0] & 0xff;
48+
buf[len] = '\0';
4949
len--;
5050
switch (band) {
5151
case 3:
52-
buf[pf] = ' ';
53-
buf[pf+1+len] = '\0';
54-
fprintf(stderr, "%s\n", buf);
55-
return SIDEBAND_REMOTE_ERROR;
52+
strbuf_addf(&outbuf, "%s%s%s", outbuf.len ? "\n" : "",
53+
PREFIX, buf + 1);
54+
retval = SIDEBAND_REMOTE_ERROR;
55+
break;
5656
case 2:
57-
buf[pf] = ' ';
58-
do {
59-
char *b = buf;
60-
int brk = 0;
57+
b = buf + 1;
6158

62-
/*
63-
* If the last buffer didn't end with a line
64-
* break then we should not print a prefix
65-
* this time around.
66-
*/
67-
if (skip_pf) {
68-
b += pf+1;
69-
} else {
70-
len += pf+1;
71-
brk += pf+1;
72-
}
73-
74-
/* Look for a line break. */
75-
for (;;) {
76-
brk++;
77-
if (brk > len) {
78-
brk = 0;
79-
break;
80-
}
81-
if (b[brk-1] == '\n' ||
82-
b[brk-1] == '\r')
83-
break;
84-
}
59+
/*
60+
* Append a suffix to each nonempty line to clear the
61+
* end of the screen line.
62+
*
63+
* The output is accumulated in a buffer and
64+
* each line is printed to stderr using
65+
* write(2) to ensure inter-process atomicity.
66+
*/
67+
while ((brk = strpbrk(b, "\n\r"))) {
68+
int linelen = brk - b;
8569

86-
/*
87-
* Let's insert a suffix to clear the end
88-
* of the screen line if a line break was
89-
* found. Also, if we don't skip the
90-
* prefix, then a non-empty string must be
91-
* present too.
92-
*/
93-
if (brk > (skip_pf ? 0 : (pf+1 + 1))) {
94-
char save[FIX_SIZE];
95-
memcpy(save, b + brk, sf);
96-
b[brk + sf - 1] = b[brk - 1];
97-
memcpy(b + brk - 1, suffix, sf);
98-
fprintf(stderr, "%.*s", brk + sf, b);
99-
memcpy(b + brk, save, sf);
100-
len -= brk;
70+
if (!outbuf.len)
71+
strbuf_addf(&outbuf, "%s", PREFIX);
72+
if (linelen > 0) {
73+
strbuf_addf(&outbuf, "%.*s%s%c",
74+
linelen, b, suffix, *brk);
10175
} else {
102-
int l = brk ? brk : len;
103-
fprintf(stderr, "%.*s", l, b);
104-
len -= l;
76+
strbuf_addf(&outbuf, "%c", *brk);
10577
}
78+
xwrite(2, outbuf.buf, outbuf.len);
79+
strbuf_reset(&outbuf);
10680

107-
skip_pf = !brk;
108-
memmove(buf + pf+1, b + brk, len);
109-
} while (len);
110-
continue;
81+
b = brk + 1;
82+
}
83+
84+
if (*b)
85+
strbuf_addf(&outbuf, "%s%s",
86+
outbuf.len ? "" : PREFIX, b);
87+
break;
11188
case 1:
112-
write_or_die(out, buf + pf+1, len);
113-
continue;
89+
write_or_die(out, buf + 1, len);
90+
break;
11491
default:
115-
fprintf(stderr, "%s: protocol error: bad band #%d\n",
116-
me, band);
117-
return SIDEBAND_PROTOCOL_ERROR;
92+
strbuf_addf(&outbuf, "%s%s: protocol error: bad band #%d",
93+
outbuf.len ? "\n" : "", me, band);
94+
retval = SIDEBAND_PROTOCOL_ERROR;
95+
break;
11896
}
11997
}
120-
return 0;
98+
99+
if (outbuf.len) {
100+
strbuf_addf(&outbuf, "\n");
101+
xwrite(2, outbuf.buf, outbuf.len);
102+
}
103+
strbuf_release(&outbuf);
104+
return retval;
121105
}
122106

123107
/*

0 commit comments

Comments
 (0)