diff options
Diffstat (limited to 'run-command.c')
-rw-r--r-- | run-command.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/run-command.c b/run-command.c index aad03ab705..e09275bd9e 100644 --- a/run-command.c +++ b/run-command.c @@ -18,26 +18,27 @@ struct child_to_clean { static struct child_to_clean *children_to_clean; static int installed_child_cleanup_handler; -static void cleanup_children(int sig) +static void cleanup_children(int sig, int in_signal) { while (children_to_clean) { struct child_to_clean *p = children_to_clean; children_to_clean = p->next; kill(p->pid, sig); - free(p); + if (!in_signal) + free(p); } } static void cleanup_children_on_signal(int sig) { - cleanup_children(sig); + cleanup_children(sig, 1); sigchain_pop(sig); raise(sig); } static void cleanup_children_on_exit(void) { - cleanup_children(SIGTERM); + cleanup_children(SIGTERM, 0); } static void mark_child_for_cleanup(pid_t pid) @@ -200,7 +201,6 @@ static int execv_shell_cmd(const char **argv) #endif #ifndef GIT_WINDOWS_NATIVE -static int child_err = 2; static int child_notifier = -1; static void notify_parent(void) @@ -212,17 +212,6 @@ static void notify_parent(void) */ xwrite(child_notifier, "", 1); } - -static NORETURN void die_child(const char *err, va_list params) -{ - vwritef(child_err, "fatal: ", err, params); - exit(128); -} - -static void error_child(const char *err, va_list params) -{ - vwritef(child_err, "error: ", err, params); -} #endif static inline void set_cloexec(int fd) @@ -232,7 +221,7 @@ static inline void set_cloexec(int fd) fcntl(fd, F_SETFD, flags | FD_CLOEXEC); } -static int wait_or_whine(pid_t pid, const char *argv0) +static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) { int status, code = -1; pid_t waiting; @@ -240,6 +229,8 @@ static int wait_or_whine(pid_t pid, const char *argv0) while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR) ; /* nothing */ + if (in_signal) + return 0; if (waiting < 0) { failed_errno = errno; @@ -362,11 +353,10 @@ fail_pipe: * in subsequent call paths use the parent's stderr. */ if (cmd->no_stderr || need_err) { - child_err = dup(2); + int child_err = dup(2); set_cloexec(child_err); + set_error_handle(fdopen(child_err, "w")); } - set_die_routine(die_child); - set_error_routine(error_child); close(notify_pipe[0]); set_cloexec(notify_pipe[1]); @@ -450,7 +440,7 @@ fail_pipe: * At this point we know that fork() succeeded, but execvp() * failed. Errors have been reported to our stderr. */ - wait_or_whine(cmd->pid, cmd->argv[0]); + wait_or_whine(cmd->pid, cmd->argv[0], 0); failed_errno = errno; cmd->pid = -1; } @@ -549,12 +539,18 @@ fail_pipe: int finish_command(struct child_process *cmd) { - int ret = wait_or_whine(cmd->pid, cmd->argv[0]); + int ret = wait_or_whine(cmd->pid, cmd->argv[0], 0); argv_array_clear(&cmd->args); argv_array_clear(&cmd->env_array); return ret; } +int finish_command_in_signal(struct child_process *cmd) +{ + return wait_or_whine(cmd->pid, cmd->argv[0], 1); +} + + int run_command(struct child_process *cmd) { int code; @@ -785,7 +781,7 @@ error: int finish_async(struct async *async) { #ifdef NO_PTHREADS - return wait_or_whine(async->pid, "child process"); + return wait_or_whine(async->pid, "child process", 0); #else void *ret = (void *)(intptr_t)(-1); @@ -795,13 +791,15 @@ int finish_async(struct async *async) #endif } -char *find_hook(const char *name) +const char *find_hook(const char *name) { - char *path = git_path("hooks/%s", name); - if (access(path, X_OK) < 0) - path = NULL; + static struct strbuf path = STRBUF_INIT; - return path; + strbuf_reset(&path); + strbuf_git_path(&path, "hooks/%s", name); + if (access(path.buf, X_OK) < 0) + return NULL; + return path.buf; } int run_hook_ve(const char *const *env, const char *name, va_list args) |