summaryrefslogtreecommitdiff
path: root/upload-pack.c
diff options
context:
space:
mode:
authorRené Scharfe <l.s.r@web.de>2020-08-12 16:52:55 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-08-17 17:29:39 (GMT)
commita698d67b08f98ddac0e6df898fbfab5b4fbd36b1 (patch)
treeac14f756e96b831cb4c304bb7b83ceabcafdbeab /upload-pack.c
parent6af3b00abc3d2af69e6bdf4f8c0843d7e3bf9c88 (diff)
downloadgit-a698d67b08f98ddac0e6df898fbfab5b4fbd36b1.zip
git-a698d67b08f98ddac0e6df898fbfab5b4fbd36b1.tar.gz
git-a698d67b08f98ddac0e6df898fbfab5b4fbd36b1.tar.bz2
upload-pack: use buffered I/O to talk to rev-list
Like f0bca72dc77 (send-pack: use buffered I/O to talk to pack-objects, 2016-06-08), significantly reduce the number of system calls and simplify the code for sending object IDs to rev-list by using stdio's buffering. Take care to handle errors immediately to get the correct error code, and to flush the buffer explicitly before closing the stream in order to catch any write errors for these last bytes. Helped-by: Chris Torek <chris.torek@gmail.com> Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'upload-pack.c')
-rw-r--r--upload-pack.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/upload-pack.c b/upload-pack.c
index 951a2b2..f6eb322 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -595,9 +595,8 @@ static int do_reachable_revlist(struct child_process *cmd,
"rev-list", "--stdin", NULL,
};
struct object *o;
- char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
+ FILE *cmd_in = NULL;
int i;
- const unsigned hexsz = the_hash_algo->hexsz;
cmd->argv = argv;
cmd->git_cmd = 1;
@@ -615,8 +614,8 @@ static int do_reachable_revlist(struct child_process *cmd,
if (start_command(cmd))
goto error;
- namebuf[0] = '^';
- namebuf[hexsz + 1] = '\n';
+ cmd_in = xfdopen(cmd->in, "w");
+
for (i = get_max_object_index(); 0 < i; ) {
o = get_indexed_object(--i);
if (!o)
@@ -625,11 +624,9 @@ static int do_reachable_revlist(struct child_process *cmd,
o->flags &= ~TMP_MARK;
if (!is_our_ref(o, allow_uor))
continue;
- memcpy(namebuf + 1, oid_to_hex(&o->oid), hexsz);
- if (write_in_full(cmd->in, namebuf, hexsz + 2) < 0)
+ if (fprintf(cmd_in, "^%s\n", oid_to_hex(&o->oid)) < 0)
goto error;
}
- namebuf[hexsz] = '\n';
for (i = 0; i < src->nr; i++) {
o = src->objects[i].item;
if (is_our_ref(o, allow_uor)) {
@@ -639,11 +636,12 @@ static int do_reachable_revlist(struct child_process *cmd,
}
if (reachable && o->type == OBJ_COMMIT)
o->flags |= TMP_MARK;
- memcpy(namebuf, oid_to_hex(&o->oid), hexsz);
- if (write_in_full(cmd->in, namebuf, hexsz + 1) < 0)
+ if (fprintf(cmd_in, "%s\n", oid_to_hex(&o->oid)) < 0)
goto error;
}
- close(cmd->in);
+ if (ferror(cmd_in) || fflush(cmd_in))
+ goto error;
+ fclose(cmd_in);
cmd->in = -1;
sigchain_pop(SIGPIPE);
@@ -652,8 +650,8 @@ static int do_reachable_revlist(struct child_process *cmd,
error:
sigchain_pop(SIGPIPE);
- if (cmd->in >= 0)
- close(cmd->in);
+ if (cmd_in)
+ fclose(cmd_in);
if (cmd->out >= 0)
close(cmd->out);
return -1;