From dcf082d24e2c869341658aa0c0489710a1b0d463 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 10 Mar 2012 23:08:08 -0800 Subject: run_hook(): enhance the interface to pass arbitrary environment Originally "run_hook()" that used to live in builtin/commit.c had a perfectly appropriate API and name for a private function to spawn a hook from "git commit" command. The only necessary tweak in the context was to optionally specify which file to use as the index file. But then we stupidly moved this private API to run-command.c without making the interface suitable for general consumption, and there is no way to tweak environment variables other than GIT_INDEX_FILE when running a hook. Correct this mistake by adding run_hook_e() that takes an array of environment variables. Signed-off-by: Junio C Hamano --- run-command.c | 49 ++++++++++++++++++++++++++++++++++++------------- run-command.h | 1 + 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/run-command.c b/run-command.c index 1db8abf984..a51d8e51c1 100644 --- a/run-command.c +++ b/run-command.c @@ -672,36 +672,59 @@ int finish_async(struct async *async) #endif } -int run_hook(const char *index_file, const char *name, ...) +static int run_hook_le(const char *const *env, + const char *name, + va_list args) { struct child_process hook; struct argv_array argv = ARGV_ARRAY_INIT; - const char *p, *env[2]; - char index[PATH_MAX]; - va_list args; + const char *p; int ret; if (access(git_path("hooks/%s", name), X_OK) < 0) return 0; - va_start(args, name); argv_array_push(&argv, git_path("hooks/%s", name)); while ((p = va_arg(args, const char *))) argv_array_push(&argv, p); - va_end(args); memset(&hook, 0, sizeof(hook)); hook.argv = argv.argv; hook.no_stdin = 1; hook.stdout_to_stderr = 1; - if (index_file) { - snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); - env[0] = index; - env[1] = NULL; - hook.env = env; - } - + hook.env = env; ret = run_command(&hook); argv_array_clear(&argv); return ret; } + +int run_hook(const char *index_file, const char *name, ...) +{ + const char *const *env = NULL, *env_buf[2]; + struct strbuf index_buf = STRBUF_INIT; + int status; + va_list args; + + va_start(args, name); + if (index_file) { + strbuf_addf(&index_buf, "GIT_INDEX_FILE=%s", index_file); + env_buf[0] = index_buf.buf; + env_buf[1] = NULL; + env = env_buf; + } + status = run_hook_le(env, name, args); + va_end(args); + strbuf_release(&index_buf); + return status; +} + +int run_hook_e(const char *const *env, const char *name, ...) +{ + int status; + va_list args; + + va_start(args, name); + status = run_hook_le(env, name, args); + va_end(args); + return status; +} diff --git a/run-command.h b/run-command.h index 44f7d2bd42..87207b90db 100644 --- a/run-command.h +++ b/run-command.h @@ -47,6 +47,7 @@ int finish_command(struct child_process *); int run_command(struct child_process *); extern int run_hook(const char *index_file, const char *name, ...); +extern int run_hook_e(const char *const *, const char *name, ...); #define RUN_COMMAND_NO_STDIN 1 #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ -- cgit v1.2.1