diff options
Diffstat (limited to 'run-command.c')
-rw-r--r-- | run-command.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/run-command.c b/run-command.c index 75abc478c6..761f0fde40 100644 --- a/run-command.c +++ b/run-command.c @@ -8,6 +8,12 @@ # define SHELL_PATH "/bin/sh" #endif +void child_process_init(struct child_process *child) +{ + memset(child, 0, sizeof(*child)); + argv_array_init(&child->args); +} + struct child_to_clean { pid_t pid; struct child_to_clean *next; @@ -279,6 +285,9 @@ int start_command(struct child_process *cmd) int failed_errno; char *str; + if (!cmd->argv) + cmd->argv = cmd->args.argv; + /* * In case of errors we must keep the promise to close FDs * that have been passed in via ->in and ->out. @@ -328,6 +337,7 @@ int start_command(struct child_process *cmd) fail_pipe: error("cannot create %s pipe for %s: %s", str, cmd->argv[0], strerror(failed_errno)); + argv_array_clear(&cmd->args); errno = failed_errno; return -1; } @@ -450,7 +460,6 @@ fail_pipe: { int fhin = 0, fhout = 1, fherr = 2; const char **sargv = cmd->argv; - char **env = environ; if (cmd->no_stdin) fhin = open("/dev/null", O_RDWR); @@ -475,24 +484,19 @@ fail_pipe: else if (cmd->out > 1) fhout = dup(cmd->out); - if (cmd->env) - env = make_augmented_environ(cmd->env); - if (cmd->git_cmd) cmd->argv = prepare_git_cmd(cmd->argv); else if (cmd->use_shell) cmd->argv = prepare_shell_cmd(cmd->argv); - cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir, - fhin, fhout, fherr); + cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env, + cmd->dir, fhin, fhout, fherr); failed_errno = errno; if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) error("cannot spawn %s: %s", cmd->argv[0], strerror(errno)); if (cmd->clean_on_exit && cmd->pid >= 0) mark_child_for_cleanup(cmd->pid); - if (cmd->env) - free_environ(env); if (cmd->git_cmd) free(cmd->argv); @@ -519,6 +523,7 @@ fail_pipe: close_pair(fderr); else if (cmd->err) close(cmd->err); + argv_array_clear(&cmd->args); errno = failed_errno; return -1; } @@ -543,7 +548,9 @@ fail_pipe: int finish_command(struct child_process *cmd) { - return wait_or_whine(cmd->pid, cmd->argv[0]); + int ret = wait_or_whine(cmd->pid, cmd->argv[0]); + argv_array_clear(&cmd->args); + return ret; } int run_command(struct child_process *cmd) @@ -554,31 +561,21 @@ int run_command(struct child_process *cmd) return finish_command(cmd); } -static void prepare_run_command_v_opt(struct child_process *cmd, - const char **argv, - int opt) -{ - memset(cmd, 0, sizeof(*cmd)); - cmd->argv = argv; - cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; - cmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0; - cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; - cmd->silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0; - cmd->use_shell = opt & RUN_USING_SHELL ? 1 : 0; - cmd->clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0; -} - int run_command_v_opt(const char **argv, int opt) { - struct child_process cmd; - prepare_run_command_v_opt(&cmd, argv, opt); - return run_command(&cmd); + return run_command_v_opt_cd_env(argv, opt, NULL, NULL); } int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env) { - struct child_process cmd; - prepare_run_command_v_opt(&cmd, argv, opt); + struct child_process cmd = CHILD_PROCESS_INIT; + cmd.argv = argv; + cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; + cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0; + cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; + cmd.silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0; + cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0; + cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0; cmd.dir = dir; cmd.env = env; return run_command(&cmd); @@ -762,29 +759,21 @@ char *find_hook(const char *name) int run_hook_ve(const char *const *env, const char *name, va_list args) { - struct child_process hook; - struct argv_array argv = ARGV_ARRAY_INIT; + struct child_process hook = CHILD_PROCESS_INIT; const char *p; - int ret; p = find_hook(name); if (!p) return 0; - argv_array_push(&argv, p); - + argv_array_push(&hook.args, p); while ((p = va_arg(args, const char *))) - argv_array_push(&argv, p); - - memset(&hook, 0, sizeof(hook)); - hook.argv = argv.argv; + argv_array_push(&hook.args, p); hook.env = env; hook.no_stdin = 1; hook.stdout_to_stderr = 1; - ret = run_command(&hook); - argv_array_clear(&argv); - return ret; + return run_command(&hook); } int run_hook_le(const char *const *env, const char *name, ...) |