From: Junio C Hamano Date: Tue, 23 Apr 2013 18:16:50 +0000 (-0700) Subject: Merge branch 'jk/receive-pack-deadlocks-with-early-failure' X-Git-Tag: v1.8.3-rc0~26 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f87f7424df3e3fba0b0211c9a7fe78fe1e526802?ds=inline;hp=-c Merge branch 'jk/receive-pack-deadlocks-with-early-failure' When receive-pack detects error in the pack header it received in order to decide which of unpack-objects or index-pack to run, it returned without closing the error stream, which led to a hang sideband thread. * jk/receive-pack-deadlocks-with-early-failure: receive-pack: close sideband fd on early pack errors --- f87f7424df3e3fba0b0211c9a7fe78fe1e526802 diff --combined builtin/receive-pack.c index ccebd74f16,ce42c0a526..e3eb5fc058 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@@ -59,11 -59,6 +59,11 @@@ static enum deny_action parse_deny_acti static int receive_pack_config(const char *var, const char *value, void *cb) { + int status = parse_hide_refs_config(var, value, "receive"); + + if (status) + return status; + if (strcmp(var, "receive.denydeletes") == 0) { deny_deletes = git_config_bool(var, value); return 0; @@@ -124,9 -119,6 +124,9 @@@ static void show_ref(const char *path, const unsigned char *sha1) { + if (ref_is_hidden(path)) + return; + if (sent_capabilities) packet_write(1, "%s %s\n", sha1_to_hex(sha1), path); else @@@ -190,6 -182,9 +190,6 @@@ struct command char ref_name[FLEX_ARRAY]; /* more */ }; -static const char pre_receive_hook[] = "hooks/pre-receive"; -static const char post_receive_hook[] = "hooks/post-receive"; - static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2))); static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2))); @@@ -247,10 -242,10 +247,10 @@@ static int run_and_feed_hook(const cha const char *argv[2]; int code; - if (access(hook_name, X_OK) < 0) + argv[0] = find_hook(hook_name); + if (!argv[0]) return 0; - argv[0] = hook_name; argv[1] = NULL; memset(&proc, 0, sizeof(proc)); @@@ -336,14 -331,15 +336,14 @@@ static int run_receive_hook(struct comm static int run_update_hook(struct command *cmd) { - static const char update_hook[] = "hooks/update"; const char *argv[5]; struct child_process proc; int code; - if (access(update_hook, X_OK) < 0) + argv[0] = find_hook("update"); + if (!argv[0]) return 0; - argv[0] = update_hook; argv[1] = cmd->ref_name; argv[2] = sha1_to_hex(cmd->old_sha1); argv[3] = sha1_to_hex(cmd->new_sha1); @@@ -536,25 -532,24 +536,25 @@@ static const char *update(struct comman } } -static char update_post_hook[] = "hooks/post-update"; - static void run_update_post_hook(struct command *commands) { struct command *cmd; int argc; const char **argv; struct child_process proc; + char *hook; + hook = find_hook("post-update"); for (argc = 0, cmd = commands; cmd; cmd = cmd->next) { if (cmd->error_string || cmd->did_not_exist) continue; argc++; } - if (!argc || access(update_post_hook, X_OK) < 0) + if (!argc || !hook) return; + argv = xmalloc(sizeof(*argv) * (2 + argc)); - argv[0] = update_post_hook; + argv[0] = hook; for (argc = 1, cmd = commands; cmd; cmd = cmd->next) { char *p; @@@ -693,20 -688,6 +693,20 @@@ static int iterate_receive_command_list return -1; /* end of list */ } +static void reject_updates_to_hidden(struct command *commands) +{ + struct command *cmd; + + for (cmd = commands; cmd; cmd = cmd->next) { + if (cmd->error_string || !ref_is_hidden(cmd->ref_name)) + continue; + if (is_null_sha1(cmd->new_sha1)) + cmd->error_string = "deny deleting a hidden ref"; + else + cmd->error_string = "deny updating a hidden ref"; + } +} + static void execute_commands(struct command *commands, const char *unpacker_error) { struct command *cmd; @@@ -723,9 -704,7 +723,9 @@@ 0, &cmd)) set_connectivity_errors(commands); - if (run_receive_hook(commands, pre_receive_hook, 0)) { + reject_updates_to_hidden(commands); + + if (run_receive_hook(commands, "pre-receive", 0)) { for (cmd = commands; cmd; cmd = cmd->next) { if (!cmd->error_string) cmd->error_string = "pre-receive hook declined"; @@@ -754,15 -733,17 +754,15 @@@ static struct command *read_head_info(v struct command *commands = NULL; struct command **p = &commands; for (;;) { - static char line[1000]; + char *line; unsigned char old_sha1[20], new_sha1[20]; struct command *cmd; char *refname; int len, reflen; - len = packet_read_line(0, line, sizeof(line)); - if (!len) + line = packet_read_line(0, &len); + if (!line) break; - if (line[len-1] == '\n') - line[--len] = 0; if (len < 83 || line[40] != ' ' || line[81] != ' ' || @@@ -826,8 -807,11 +826,11 @@@ static const char *unpack(int err_fd : 0); hdr_err = parse_pack_header(&hdr); - if (hdr_err) + if (hdr_err) { + if (err_fd > 0) + close(err_fd); return hdr_err; + } snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%"PRIu32",%"PRIu32, ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries)); @@@ -930,7 -914,7 +933,7 @@@ static void report(struct command *comm if (use_sideband) send_sideband(1, 1, buf.buf, buf.len, use_sideband); else - safe_write(1, buf.buf, buf.len); + write_or_die(1, buf.buf, buf.len); strbuf_release(&buf); } @@@ -1013,7 -997,7 +1016,7 @@@ int cmd_receive_pack(int argc, const ch unlink_or_warn(pack_lockfile); if (report_status) report(commands, unpack_status); - run_receive_hook(commands, post_receive_hook, 1); + run_receive_hook(commands, "post-receive", 1); run_update_post_hook(commands); if (auto_gc) { const char *argv_gc_auto[] = {