diff options
-rw-r--r-- | connect.c | 3 | ||||
-rw-r--r-- | pkt-line.c | 21 | ||||
-rw-r--r-- | pkt-line.h | 27 |
3 files changed, 36 insertions, 15 deletions
@@ -76,7 +76,8 @@ struct ref **get_remote_heads(int in, struct ref **list, char *name; int len, name_len; - len = packet_read(in, buffer, sizeof(buffer)); + len = packet_read(in, buffer, sizeof(buffer), + PACKET_READ_GENTLE_ON_EOF); if (len < 0) die_initial_contact(got_at_least_one_head); diff --git a/pkt-line.c b/pkt-line.c index 699c2dd3b9..8700cf8add 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -103,13 +103,13 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...) strbuf_add(buf, buffer, n); } -static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail) +static int safe_read(int fd, void *buffer, unsigned size, int options) { ssize_t ret = read_in_full(fd, buffer, size); if (ret < 0) die_errno("read error"); else if (ret < size) { - if (return_line_fail) + if (options & PACKET_READ_GENTLE_ON_EOF) return -1; die("The remote end hung up unexpectedly"); @@ -143,13 +143,13 @@ static int packet_length(const char *linelen) return len; } -static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail) +int packet_read(int fd, char *buffer, unsigned size, int options) { int len, ret; char linelen[4]; - ret = safe_read(fd, linelen, 4, return_line_fail); - if (return_line_fail && ret < 0) + ret = safe_read(fd, linelen, 4, options); + if (ret < 0) return ret; len = packet_length(linelen); if (len < 0) @@ -161,22 +161,17 @@ static int packet_read_internal(int fd, char *buffer, unsigned size, int return_ len -= 4; if (len >= size) die("protocol error: bad line length %d", len); - ret = safe_read(fd, buffer, len, return_line_fail); - if (return_line_fail && ret < 0) + ret = safe_read(fd, buffer, len, options); + if (ret < 0) return ret; buffer[len] = 0; packet_trace(buffer, len, 0); return len; } -int packet_read(int fd, char *buffer, unsigned size) -{ - return packet_read_internal(fd, buffer, size, 1); -} - int packet_read_line(int fd, char *buffer, unsigned size) { - return packet_read_internal(fd, buffer, size, 0); + return packet_read(fd, buffer, size, 0); } int packet_get_line(struct strbuf *out, diff --git a/pkt-line.h b/pkt-line.h index 3b6c19c4e4..8cd326c922 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -24,8 +24,33 @@ void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2 void packet_buf_flush(struct strbuf *buf); void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +/* + * Read a packetized line from the descriptor into the buffer, which must be at + * least size bytes long. The return value specifies the number of bytes read + * into the buffer. + * + * If options does not contain PACKET_READ_GENTLE_ON_EOF, we will die under any + * of the following conditions: + * + * 1. Read error from descriptor. + * + * 2. Protocol error from the remote (e.g., bogus length characters). + * + * 3. Receiving a packet larger than "size" bytes. + * + * 4. Truncated output from the remote (e.g., we expected a packet but got + * EOF, or we got a partial packet followed by EOF). + * + * If options does contain PACKET_READ_GENTLE_ON_EOF, we will not die on + * condition 4 (truncated input), but instead return -1. However, we will still + * die for the other 3 conditions. + */ +#define PACKET_READ_GENTLE_ON_EOF (1u<<0) +int packet_read(int fd, char *buffer, unsigned size, int options); + +/* Historical convenience wrapper for packet_read that sets no options */ int packet_read_line(int fd, char *buffer, unsigned size); -int packet_read(int fd, char *buffer, unsigned size); + int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len); #endif |