pkt-line: provide a generic reading function with options
authorJeff King <peff@peff.net>
Wed, 20 Feb 2013 20:02:10 +0000 (15:02 -0500)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Feb 2013 21:42:21 +0000 (13:42 -0800)
Originally we had a single function for reading packetized
data: packet_read_line. Commit 46284dd grew a more "gentle"
form, packet_read, that returns an error instead of dying
upon reading a truncated input stream. However, it is not
clear from the names which should be called, or what the
difference is.

Let's instead make packet_read be a generic public interface
that can take option flags, and update the single callsite
that uses it. This is less code, more clear, and paves the
way for introducing more options into the generic interface
later. The function signature is changed, so there should be
no hidden conflicts with topics in flight.

While we're at it, we'll document how error conditions are
handled based on the options, and rename the confusing
"return_line_fail" option to "gentle_on_eof". While we are
cleaning up the names, we can drop the "return_line_fail"
checks in packet_read_internal entirely. They look like
this:

ret = safe_read(..., return_line_fail);
if (return_line_fail && ret < 0)
...

The check for return_line_fail is a no-op; safe_read will
only ever return an error value if return_line_fail was true
in the first place.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
connect.c
pkt-line.c
pkt-line.h
index 49e56ba35a645359b0d7c1f7bbc9e2108b3424d9..0aa202f885dce3791d6c92bfa434c084f424b145 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -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);
 
index 699c2dd3b9a60c147f71cd9e0a6f0e52c548c2f1..8700cf8add94507c67959f1939b9710a7d5cbf52 100644 (file)
@@ -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,
index 3b6c19c4e46449aa366acdde85b6d5498257e0cd..8cd326c92237bd5ecc67587e2199c5ea4c1bae67 100644 (file)
@@ -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