mirror of
https://github.com/git/git
synced 2024-11-04 16:17:49 +00:00
sideband: reverse its dependency on pkt-line
A subsequent patch will teach struct packet_reader a new field that, if set, instructs it to interpret read data as multiplexed. This will create a dependency from pkt-line to sideband. To avoid a circular dependency, split recv_sideband() into 2 parts: the reading loop (left in recv_sideband()) and the processing of the contents (in demultiplex_sideband()), and move the former into pkt-line. This reverses the direction of dependency: sideband no longer depends on pkt-line, and pkt-line now depends on sideband. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
bc2e795cea
commit
fbd76cd450
4 changed files with 143 additions and 97 deletions
23
pkt-line.c
23
pkt-line.c
|
@ -439,6 +439,29 @@ ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out)
|
|||
return sb_out->len - orig_len;
|
||||
}
|
||||
|
||||
int recv_sideband(const char *me, int in_stream, int out)
|
||||
{
|
||||
char buf[LARGE_PACKET_MAX + 1];
|
||||
int len;
|
||||
struct strbuf scratch = STRBUF_INIT;
|
||||
enum sideband_type sideband_type;
|
||||
|
||||
while (1) {
|
||||
len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX,
|
||||
0);
|
||||
if (!demultiplex_sideband(me, buf, len, &scratch,
|
||||
&sideband_type))
|
||||
continue;
|
||||
switch (sideband_type) {
|
||||
case SIDEBAND_PRIMARY:
|
||||
write_or_die(out, buf + 1, len - 1);
|
||||
break;
|
||||
default: /* errors: message already written */
|
||||
return sideband_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Packet Reader Functions */
|
||||
void packet_reader_init(struct packet_reader *reader, int fd,
|
||||
char *src_buffer, size_t src_len,
|
||||
|
|
16
pkt-line.h
16
pkt-line.h
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "git-compat-util.h"
|
||||
#include "strbuf.h"
|
||||
#include "sideband.h"
|
||||
|
||||
/*
|
||||
* Write a packetized stream, where each line is preceded by
|
||||
|
@ -120,6 +121,21 @@ char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
|
|||
*/
|
||||
ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out);
|
||||
|
||||
/*
|
||||
* Receive multiplexed output stream over git native protocol.
|
||||
* in_stream is the input stream from the remote, which carries data
|
||||
* in pkt_line format with band designator. Demultiplex it into out
|
||||
* and err and return error appropriately. Band #1 carries the
|
||||
* primary payload. Things coming over band #2 is not necessarily
|
||||
* error; they are usually informative message on the standard error
|
||||
* stream, aka "verbose"). A message over band #3 is a signal that
|
||||
* the remote died unexpectedly. A flush() concludes the stream.
|
||||
*
|
||||
* Returns SIDEBAND_FLUSH upon a normal conclusion, and SIDEBAND_PROTOCOL_ERROR
|
||||
* or SIDEBAND_REMOTE_ERROR if an error occurred.
|
||||
*/
|
||||
int recv_sideband(const char *me, int in_stream, int out);
|
||||
|
||||
struct packet_reader {
|
||||
/* source file descriptor */
|
||||
int fd;
|
||||
|
|
177
sideband.c
177
sideband.c
|
@ -1,7 +1,6 @@
|
|||
#include "cache.h"
|
||||
#include "color.h"
|
||||
#include "config.h"
|
||||
#include "pkt-line.h"
|
||||
#include "sideband.h"
|
||||
#include "help.h"
|
||||
|
||||
|
@ -109,109 +108,99 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Receive multiplexed output stream over git native protocol.
|
||||
* in_stream is the input stream from the remote, which carries data
|
||||
* in pkt_line format with band designator. Demultiplex it into out
|
||||
* and err and return error appropriately. Band #1 carries the
|
||||
* primary payload. Things coming over band #2 is not necessarily
|
||||
* error; they are usually informative message on the standard error
|
||||
* stream, aka "verbose"). A message over band #3 is a signal that
|
||||
* the remote died unexpectedly. A flush() concludes the stream.
|
||||
*/
|
||||
|
||||
#define DISPLAY_PREFIX "remote: "
|
||||
|
||||
#define ANSI_SUFFIX "\033[K"
|
||||
#define DUMB_SUFFIX " "
|
||||
|
||||
int recv_sideband(const char *me, int in_stream, int out)
|
||||
int demultiplex_sideband(const char *me, char *buf, int len,
|
||||
struct strbuf *scratch,
|
||||
enum sideband_type *sideband_type)
|
||||
{
|
||||
const char *suffix;
|
||||
char buf[LARGE_PACKET_MAX + 1];
|
||||
struct strbuf outbuf = STRBUF_INIT;
|
||||
int retval = 0;
|
||||
static const char *suffix;
|
||||
const char *b, *brk;
|
||||
int band;
|
||||
|
||||
if (isatty(2) && !is_terminal_dumb())
|
||||
suffix = ANSI_SUFFIX;
|
||||
else
|
||||
suffix = DUMB_SUFFIX;
|
||||
|
||||
while (!retval) {
|
||||
const char *b, *brk;
|
||||
int band, len;
|
||||
len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX, 0);
|
||||
if (len == 0)
|
||||
break;
|
||||
if (len < 1) {
|
||||
strbuf_addf(&outbuf,
|
||||
"%s%s: protocol error: no band designator",
|
||||
outbuf.len ? "\n" : "", me);
|
||||
retval = SIDEBAND_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
band = buf[0] & 0xff;
|
||||
buf[len] = '\0';
|
||||
len--;
|
||||
switch (band) {
|
||||
case 3:
|
||||
strbuf_addf(&outbuf, "%s%s", outbuf.len ? "\n" : "",
|
||||
DISPLAY_PREFIX);
|
||||
maybe_colorize_sideband(&outbuf, buf + 1, len);
|
||||
|
||||
retval = SIDEBAND_REMOTE_ERROR;
|
||||
break;
|
||||
case 2:
|
||||
b = buf + 1;
|
||||
|
||||
/*
|
||||
* Append a suffix to each nonempty line to clear the
|
||||
* end of the screen line.
|
||||
*
|
||||
* The output is accumulated in a buffer and
|
||||
* each line is printed to stderr using
|
||||
* write(2) to ensure inter-process atomicity.
|
||||
*/
|
||||
while ((brk = strpbrk(b, "\n\r"))) {
|
||||
int linelen = brk - b;
|
||||
|
||||
if (!outbuf.len)
|
||||
strbuf_addstr(&outbuf, DISPLAY_PREFIX);
|
||||
if (linelen > 0) {
|
||||
maybe_colorize_sideband(&outbuf, b, linelen);
|
||||
strbuf_addstr(&outbuf, suffix);
|
||||
}
|
||||
|
||||
strbuf_addch(&outbuf, *brk);
|
||||
xwrite(2, outbuf.buf, outbuf.len);
|
||||
strbuf_reset(&outbuf);
|
||||
|
||||
b = brk + 1;
|
||||
}
|
||||
|
||||
if (*b) {
|
||||
strbuf_addstr(&outbuf, outbuf.len ?
|
||||
"" : DISPLAY_PREFIX);
|
||||
maybe_colorize_sideband(&outbuf, b, strlen(b));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
write_or_die(out, buf + 1, len);
|
||||
break;
|
||||
default:
|
||||
strbuf_addf(&outbuf, "%s%s: protocol error: bad band #%d",
|
||||
outbuf.len ? "\n" : "", me, band);
|
||||
retval = SIDEBAND_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
if (!suffix) {
|
||||
if (isatty(2) && !is_terminal_dumb())
|
||||
suffix = ANSI_SUFFIX;
|
||||
else
|
||||
suffix = DUMB_SUFFIX;
|
||||
}
|
||||
|
||||
if (outbuf.len) {
|
||||
strbuf_addch(&outbuf, '\n');
|
||||
xwrite(2, outbuf.buf, outbuf.len);
|
||||
if (len == 0) {
|
||||
*sideband_type = SIDEBAND_FLUSH;
|
||||
goto cleanup;
|
||||
}
|
||||
strbuf_release(&outbuf);
|
||||
return retval;
|
||||
if (len < 1) {
|
||||
strbuf_addf(scratch,
|
||||
"%s%s: protocol error: no band designator",
|
||||
scratch->len ? "\n" : "", me);
|
||||
*sideband_type = SIDEBAND_PROTOCOL_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
band = buf[0] & 0xff;
|
||||
buf[len] = '\0';
|
||||
len--;
|
||||
switch (band) {
|
||||
case 3:
|
||||
strbuf_addf(scratch, "%s%s", scratch->len ? "\n" : "",
|
||||
DISPLAY_PREFIX);
|
||||
maybe_colorize_sideband(scratch, buf + 1, len);
|
||||
|
||||
*sideband_type = SIDEBAND_REMOTE_ERROR;
|
||||
break;
|
||||
case 2:
|
||||
b = buf + 1;
|
||||
|
||||
/*
|
||||
* Append a suffix to each nonempty line to clear the
|
||||
* end of the screen line.
|
||||
*
|
||||
* The output is accumulated in a buffer and
|
||||
* each line is printed to stderr using
|
||||
* write(2) to ensure inter-process atomicity.
|
||||
*/
|
||||
while ((brk = strpbrk(b, "\n\r"))) {
|
||||
int linelen = brk - b;
|
||||
|
||||
if (!scratch->len)
|
||||
strbuf_addstr(scratch, DISPLAY_PREFIX);
|
||||
if (linelen > 0) {
|
||||
maybe_colorize_sideband(scratch, b, linelen);
|
||||
strbuf_addstr(scratch, suffix);
|
||||
}
|
||||
|
||||
strbuf_addch(scratch, *brk);
|
||||
xwrite(2, scratch->buf, scratch->len);
|
||||
strbuf_reset(scratch);
|
||||
|
||||
b = brk + 1;
|
||||
}
|
||||
|
||||
if (*b) {
|
||||
strbuf_addstr(scratch, scratch->len ?
|
||||
"" : DISPLAY_PREFIX);
|
||||
maybe_colorize_sideband(scratch, b, strlen(b));
|
||||
}
|
||||
return 0;
|
||||
case 1:
|
||||
*sideband_type = SIDEBAND_PRIMARY;
|
||||
break;
|
||||
default:
|
||||
strbuf_addf(scratch, "%s%s: protocol error: bad band #%d",
|
||||
scratch->len ? "\n" : "", me, band);
|
||||
*sideband_type = SIDEBAND_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (scratch->len) {
|
||||
strbuf_addch(scratch, '\n');
|
||||
xwrite(2, scratch->buf, scratch->len);
|
||||
}
|
||||
strbuf_release(scratch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
24
sideband.h
24
sideband.h
|
@ -1,10 +1,28 @@
|
|||
#ifndef SIDEBAND_H
|
||||
#define SIDEBAND_H
|
||||
|
||||
#define SIDEBAND_PROTOCOL_ERROR -2
|
||||
#define SIDEBAND_REMOTE_ERROR -1
|
||||
enum sideband_type {
|
||||
SIDEBAND_PROTOCOL_ERROR = -2,
|
||||
SIDEBAND_REMOTE_ERROR = -1,
|
||||
SIDEBAND_FLUSH = 0,
|
||||
SIDEBAND_PRIMARY = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Inspects a multiplexed packet read from the remote. If this packet is a
|
||||
* progress packet and thus should not be processed by the caller, returns 0.
|
||||
* Otherwise, returns 1, releases scratch, and sets sideband_type.
|
||||
*
|
||||
* If this packet is SIDEBAND_PROTOCOL_ERROR, SIDEBAND_REMOTE_ERROR, or a
|
||||
* progress packet, also prints a message to stderr.
|
||||
*
|
||||
* scratch must be a struct strbuf allocated by the caller. It is used to store
|
||||
* progress messages split across multiple packets.
|
||||
*/
|
||||
int demultiplex_sideband(const char *me, char *buf, int len,
|
||||
struct strbuf *scratch,
|
||||
enum sideband_type *sideband_type);
|
||||
|
||||
int recv_sideband(const char *me, int in_stream, int out);
|
||||
void send_sideband(int fd, int band, const char *data, ssize_t sz, int packet_max);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue