summaryrefslogtreecommitdiff
path: root/builtin/receive-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/receive-pack.c')
-rw-r--r--builtin/receive-pack.c94
1 files changed, 69 insertions, 25 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index bb9909c..f1f0f7b 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -977,15 +977,25 @@ static int read_proc_receive_report(struct packet_reader *reader,
int new_report = 0;
int code = 0;
int once = 0;
+ int response = 0;
for (;;) {
struct object_id old_oid, new_oid;
const char *head;
const char *refname;
char *p;
-
- if (packet_reader_read(reader) != PACKET_READ_NORMAL)
+ enum packet_read_status status;
+
+ status = packet_reader_read(reader);
+ if (status != PACKET_READ_NORMAL) {
+ /* Check whether proc-receive exited abnormally */
+ if (status == PACKET_READ_EOF && !response) {
+ strbuf_addstr(errmsg, "proc-receive exited abnormally");
+ return -1;
+ }
break;
+ }
+ response++;
head = reader->line;
p = strchr(head, ' ');
@@ -1145,31 +1155,49 @@ static int run_proc_receive_hook(struct command *commands,
if (use_push_options)
strbuf_addstr(&cap, " push-options");
if (cap.len) {
- packet_write_fmt(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
+ code = packet_write_fmt_gently(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
strbuf_release(&cap);
} else {
- packet_write_fmt(proc.in, "version=1\n");
+ code = packet_write_fmt_gently(proc.in, "version=1\n");
}
- packet_flush(proc.in);
+ if (!code)
+ code = packet_flush_gently(proc.in);
- for (;;) {
- int linelen;
+ if (!code)
+ for (;;) {
+ int linelen;
+ enum packet_read_status status;
- if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
- break;
+ status = packet_reader_read(&reader);
+ if (status != PACKET_READ_NORMAL) {
+ /* Check whether proc-receive exited abnormally */
+ if (status == PACKET_READ_EOF)
+ code = -1;
+ break;
+ }
- if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
- version = atoi(reader.line + 8);
- linelen = strlen(reader.line);
- if (linelen < reader.pktlen) {
- const char *feature_list = reader.line + linelen + 1;
- if (parse_feature_request(feature_list, "push-options"))
- hook_use_push_options = 1;
+ if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
+ version = atoi(reader.line + 8);
+ linelen = strlen(reader.line);
+ if (linelen < reader.pktlen) {
+ const char *feature_list = reader.line + linelen + 1;
+ if (parse_feature_request(feature_list, "push-options"))
+ hook_use_push_options = 1;
+ }
}
}
+
+ if (code) {
+ strbuf_addstr(&errmsg, "fail to negotiate version with proc-receive hook");
+ goto cleanup;
}
- if (version != 1) {
+ switch (version) {
+ case 0:
+ /* fallthrough */
+ case 1:
+ break;
+ default:
strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
version);
code = -1;
@@ -1180,20 +1208,36 @@ static int run_proc_receive_hook(struct command *commands,
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->run_proc_receive || cmd->skip_update || cmd->error_string)
continue;
- packet_write_fmt(proc.in, "%s %s %s",
- oid_to_hex(&cmd->old_oid),
- oid_to_hex(&cmd->new_oid),
- cmd->ref_name);
+ code = packet_write_fmt_gently(proc.in, "%s %s %s",
+ oid_to_hex(&cmd->old_oid),
+ oid_to_hex(&cmd->new_oid),
+ cmd->ref_name);
+ if (code)
+ break;
+ }
+ if (!code)
+ code = packet_flush_gently(proc.in);
+ if (code) {
+ strbuf_addstr(&errmsg, "fail to write commands to proc-receive hook");
+ goto cleanup;
}
- packet_flush(proc.in);
/* Send push options */
if (hook_use_push_options) {
struct string_list_item *item;
- for_each_string_list_item(item, push_options)
- packet_write_fmt(proc.in, "%s", item->string);
- packet_flush(proc.in);
+ for_each_string_list_item(item, push_options) {
+ code = packet_write_fmt_gently(proc.in, "%s", item->string);
+ if (code)
+ break;
+ }
+ if (!code)
+ code = packet_flush_gently(proc.in);
+ if (code) {
+ strbuf_addstr(&errmsg,
+ "fail to write push-options to proc-receive hook");
+ goto cleanup;
+ }
}
/* Read result from proc-receive */