From: Junio C Hamano Date: Fri, 31 Oct 2014 18:49:53 +0000 (-0700) Subject: Merge branch 'jc/push-cert' X-Git-Tag: v2.2.0-rc0~2 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/1d42cf3c6c578003f35d32cb7b98aa19a96a17c1?ds=inline;hp=-c Merge branch 'jc/push-cert' * jc/push-cert: receive-pack: avoid minor leak in case start_async() fails --- 1d42cf3c6c578003f35d32cb7b98aa19a96a17c1 diff --combined builtin/receive-pack.c index fc0393779c,99136526c9..32fc540ef3 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@@ -1,5 -1,4 +1,5 @@@ #include "builtin.h" +#include "lockfile.h" #include "pack.h" #include "refs.h" #include "pkt-line.h" @@@ -18,7 -17,6 +18,7 @@@ #include "version.h" #include "tag.h" #include "gpg-interface.h" +#include "sigchain.h" static const char receive_pack_usage[] = "git receive-pack "; @@@ -453,6 -451,7 +453,6 @@@ leave static void prepare_push_cert_sha1(struct child_process *proc) { static int already_done; - struct argv_array env = ARGV_ARRAY_INIT; if (!push_cert.len) return; @@@ -486,33 -485,27 +486,33 @@@ nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_sha1(push_cert_sha1)) { - argv_array_pushf(&env, "GIT_PUSH_CERT=%s", sha1_to_hex(push_cert_sha1)); - argv_array_pushf(&env, "GIT_PUSH_CERT_SIGNER=%s", + argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", + sha1_to_hex(push_cert_sha1)); + argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", sigcheck.signer ? sigcheck.signer : ""); - argv_array_pushf(&env, "GIT_PUSH_CERT_KEY=%s", + argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", sigcheck.key ? sigcheck.key : ""); - argv_array_pushf(&env, "GIT_PUSH_CERT_STATUS=%c", sigcheck.result); + argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", + sigcheck.result); if (push_cert_nonce) { - argv_array_pushf(&env, "GIT_PUSH_CERT_NONCE=%s", push_cert_nonce); - argv_array_pushf(&env, "GIT_PUSH_CERT_NONCE_STATUS=%s", nonce_status); + argv_array_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE=%s", + push_cert_nonce); + argv_array_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE_STATUS=%s", + nonce_status); if (nonce_status == NONCE_SLOP) - argv_array_pushf(&env, "GIT_PUSH_CERT_NONCE_SLOP=%ld", + argv_array_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE_SLOP=%ld", nonce_stamp_slop); } - proc->env = env.argv; } } typedef int (*feed_fn)(void *, const char **, size_t *); static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state) { - struct child_process proc; + struct child_process proc = CHILD_PROCESS_INIT; struct async muxer; const char *argv[2]; int code; @@@ -523,12 -516,11 +523,10 @@@ argv[1] = NULL; - memset(&proc, 0, sizeof(proc)); proc.argv = argv; proc.in = -1; proc.stdout_to_stderr = 1; - prepare_push_cert_sha1(&proc); - if (use_sideband) { memset(&muxer, 0, sizeof(muxer)); muxer.proc = copy_to_sideband; @@@ -539,6 -531,8 +537,8 @@@ proc.err = muxer.in; } + prepare_push_cert_sha1(&proc); + code = start_command(&proc); if (code) { if (use_sideband) @@@ -546,8 -540,6 +546,8 @@@ return code; } + sigchain_push(SIGPIPE, SIG_IGN); + while (1) { const char *buf; size_t n; @@@ -559,9 -551,6 +559,9 @@@ close(proc.in); if (use_sideband) finish_async(&muxer); + + sigchain_pop(SIGPIPE); + return finish_command(&proc); } @@@ -613,7 -602,7 +613,7 @@@ static int run_receive_hook(struct comm static int run_update_hook(struct command *cmd) { const char *argv[5]; - struct child_process proc; + struct child_process proc = CHILD_PROCESS_INIT; int code; argv[0] = find_hook("update"); @@@ -625,6 -614,7 +625,6 @@@ argv[3] = sha1_to_hex(cmd->new_sha1); argv[4] = NULL; - memset(&proc, 0, sizeof(proc)); proc.no_stdin = 1; proc.stdout_to_stderr = 1; proc.err = use_sideband ? -1 : 0; @@@ -737,6 -727,7 +737,6 @@@ static const char *update(struct comman const char *namespaced_name; unsigned char *old_sha1 = cmd->old_sha1; unsigned char *new_sha1 = cmd->new_sha1; - struct ref_lock *lock; /* only refs/... are allowed */ if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) { @@@ -837,28 -828,19 +837,28 @@@ return NULL; /* good */ } else { + struct strbuf err = STRBUF_INIT; + struct ref_transaction *transaction; + if (shallow_update && si->shallow_ref[cmd->index] && update_shallow_ref(cmd, si)) return "shallow error"; - lock = lock_any_ref_for_update(namespaced_name, old_sha1, - 0, NULL); - if (!lock) { - rp_error("failed to lock %s", name); - return "failed to lock"; - } - if (write_ref_sha1(lock, new_sha1, "push")) { - return "failed to write"; /* error() already called */ + transaction = ref_transaction_begin(&err); + if (!transaction || + ref_transaction_update(transaction, namespaced_name, + new_sha1, old_sha1, 0, 1, "push", + &err) || + ref_transaction_commit(transaction, &err)) { + ref_transaction_free(transaction); + + rp_error("%s", err.buf); + strbuf_release(&err); + return "failed to update ref"; } + + ref_transaction_free(transaction); + strbuf_release(&err); return NULL; /* good */ } } @@@ -868,7 -850,7 +868,7 @@@ static void run_update_post_hook(struc struct command *cmd; int argc; const char **argv; - struct child_process proc; + struct child_process proc = CHILD_PROCESS_INIT; char *hook; hook = find_hook("post-update"); @@@ -891,6 -873,7 +891,6 @@@ } argv[argc] = NULL; - memset(&proc, 0, sizeof(proc)); proc.no_stdin = 1; proc.stdout_to_stderr = 1; proc.err = use_sideband ? -1 : 0; @@@ -914,7 -897,7 +914,7 @@@ static void check_aliased_update(struc int flag; strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name); - dst_name = resolve_ref_unsafe(buf.buf, sha1, 0, &flag); + dst_name = resolve_ref_unsafe(buf.buf, 0, sha1, &flag); strbuf_release(&buf); if (!(flag & REF_ISSYMREF)) @@@ -1075,7 -1058,7 +1075,7 @@@ static void execute_commands(struct com check_aliased_updates(commands); free(head_name_to_free); - head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL); + head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL); checked_connectivity = 1; for (cmd = commands; cmd; cmd = cmd->next) { @@@ -1236,10 -1219,11 +1236,10 @@@ static const char *pack_lockfile static const char *unpack(int err_fd, struct shallow_info *si) { struct pack_header hdr; - struct argv_array av = ARGV_ARRAY_INIT; const char *hdr_err; int status; char hdr_arg[38]; - struct child_process child; + struct child_process child = CHILD_PROCESS_INIT; int fsck_objects = (receive_fsck_objects >= 0 ? receive_fsck_objects : transfer_fsck_objects >= 0 @@@ -1258,16 -1242,17 +1258,16 @@@ if (si->nr_ours || si->nr_theirs) { alt_shallow_file = setup_temporary_shallow(si->shallow); - argv_array_pushl(&av, "--shallow-file", alt_shallow_file, NULL); + argv_array_push(&child.args, "--shallow-file"); + argv_array_push(&child.args, alt_shallow_file); } - memset(&child, 0, sizeof(child)); if (ntohl(hdr.hdr_entries) < unpack_limit) { - argv_array_pushl(&av, "unpack-objects", hdr_arg, NULL); + argv_array_pushl(&child.args, "unpack-objects", hdr_arg, NULL); if (quiet) - argv_array_push(&av, "-q"); + argv_array_push(&child.args, "-q"); if (fsck_objects) - argv_array_push(&av, "--strict"); - child.argv = av.argv; + argv_array_push(&child.args, "--strict"); child.no_stdout = 1; child.err = err_fd; child.git_cmd = 1; @@@ -1282,12 -1267,13 +1282,12 @@@ if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) strcpy(keep_arg + s, "localhost"); - argv_array_pushl(&av, "index-pack", + argv_array_pushl(&child.args, "index-pack", "--stdin", hdr_arg, keep_arg, NULL); if (fsck_objects) - argv_array_push(&av, "--strict"); + argv_array_push(&child.args, "--strict"); if (fix_thin) - argv_array_push(&av, "--fix-thin"); - child.argv = av.argv; + argv_array_push(&child.args, "--fix-thin"); child.out = -1; child.err = err_fd; child.git_cmd = 1;