]> git.ipfire.org Git - thirdparty/git.git/commitdiff
upload-pack: refactor reading of pack-objects out
authorJonathan Tan <jonathantanmy@google.com>
Wed, 10 Jun 2020 20:57:21 +0000 (13:57 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 11 Jun 2020 01:06:34 +0000 (18:06 -0700)
Subsequent patches will change how the output of pack-objects is
processed, so extract that processing into its own function.

Currently, at most 1 character can be buffered (in the "buffered" local
variable). One of those patches will require a larger buffer, so replace
that "buffered" local variable with a buffer array.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
upload-pack.c

index bc7e3ca19dd4deea074b0680083f4fde1c5b1910..da1f749620376ac0371cb3c514baaf26d0854c75 100644 (file)
@@ -173,13 +173,52 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
        return 0;
 }
 
+struct output_state {
+       char buffer[8193];
+       int used;
+};
+
+static int relay_pack_data(int pack_objects_out, struct output_state *os,
+                          int use_sideband)
+{
+       /*
+        * We keep the last byte to ourselves
+        * in case we detect broken rev-list, so that we
+        * can leave the stream corrupted.  This is
+        * unfortunate -- unpack-objects would happily
+        * accept a valid packdata with trailing garbage,
+        * so appending garbage after we pass all the
+        * pack data is not good enough to signal
+        * breakage to downstream.
+        */
+       ssize_t readsz;
+
+       readsz = xread(pack_objects_out, os->buffer + os->used,
+                      sizeof(os->buffer) - os->used);
+       if (readsz < 0) {
+               return readsz;
+       }
+       os->used += readsz;
+
+       if (os->used > 1) {
+               send_client_data(1, os->buffer, os->used - 1, use_sideband);
+               os->buffer[0] = os->buffer[os->used - 1];
+               os->used = 1;
+       } else {
+               send_client_data(1, os->buffer, os->used, use_sideband);
+               os->used = 0;
+       }
+
+       return readsz;
+}
+
 static void create_pack_file(struct upload_pack_data *pack_data)
 {
        struct child_process pack_objects = CHILD_PROCESS_INIT;
-       char data[8193], progress[128];
+       struct output_state output_state = { { 0 } };
+       char progress[128];
        char abort_msg[] = "aborting due to possible repository "
                "corruption on the remote side.";
-       int buffered = -1;
        ssize_t sz;
        int i;
        FILE *pipe_fd;
@@ -312,40 +351,16 @@ static void create_pack_file(struct upload_pack_data *pack_data)
                        continue;
                }
                if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
-                       /* Data ready; we keep the last byte to ourselves
-                        * in case we detect broken rev-list, so that we
-                        * can leave the stream corrupted.  This is
-                        * unfortunate -- unpack-objects would happily
-                        * accept a valid packdata with trailing garbage,
-                        * so appending garbage after we pass all the
-                        * pack data is not good enough to signal
-                        * breakage to downstream.
-                        */
-                       char *cp = data;
-                       ssize_t outsz = 0;
-                       if (0 <= buffered) {
-                               *cp++ = buffered;
-                               outsz++;
-                       }
-                       sz = xread(pack_objects.out, cp,
-                                 sizeof(data) - outsz);
-                       if (0 < sz)
-                               ;
-                       else if (sz == 0) {
+                       int result = relay_pack_data(pack_objects.out,
+                                                    &output_state,
+                                                    pack_data->use_sideband);
+
+                       if (result == 0) {
                                close(pack_objects.out);
                                pack_objects.out = -1;
-                       }
-                       else
+                       } else if (result < 0) {
                                goto fail;
-                       sz += outsz;
-                       if (1 < sz) {
-                               buffered = data[sz-1] & 0xFF;
-                               sz--;
                        }
-                       else
-                               buffered = -1;
-                       send_client_data(1, data, sz,
-                                        pack_data->use_sideband);
                }
 
                /*
@@ -370,9 +385,8 @@ static void create_pack_file(struct upload_pack_data *pack_data)
        }
 
        /* flush the data */
-       if (0 <= buffered) {
-               data[0] = buffered;
-               send_client_data(1, data, 1,
+       if (output_state.used > 0) {
+               send_client_data(1, output_state.buffer, output_state.used,
                                 pack_data->use_sideband);
                fprintf(stderr, "flushed.\n");
        }