diff.c: Do not initialize a variable, which gets reassigned anyway.
[gitweb.git] / run-command.c
index ec1a664755bb70e049259ced0917ee0ce2082d71..1b32a12a29b64fcc7d8b2401b00fb8a70ff81bad 100644 (file)
@@ -226,7 +226,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, int silent_exec_failure)
+static int wait_or_whine(pid_t pid, const char *argv0)
 {
        int status, code = -1;
        pid_t waiting;
@@ -242,13 +242,14 @@ static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
                error("waitpid is confused (%s)", argv0);
        } else if (WIFSIGNALED(status)) {
                code = WTERMSIG(status);
-               error("%s died of signal %d", argv0, code);
+               if (code != SIGINT && code != SIGQUIT)
+                       error("%s died of signal %d", argv0, code);
                /*
                 * This return value is chosen so that code & 0xff
                 * mimics the exit code that a POSIX shell would report for
                 * a program that died from this signal.
                 */
-               code -= 128;
+               code += 128;
        } else if (WIFEXITED(status)) {
                code = WEXITSTATUS(status);
                /*
@@ -272,7 +273,7 @@ int start_command(struct child_process *cmd)
 {
        int need_in, need_out, need_err;
        int fdin[2], fdout[2], fderr[2];
-       int failed_errno = failed_errno;
+       int failed_errno;
        char *str;
 
        /*
@@ -340,6 +341,7 @@ int start_command(struct child_process *cmd)
                notify_pipe[0] = notify_pipe[1] = -1;
 
        cmd->pid = fork();
+       failed_errno = errno;
        if (!cmd->pid) {
                /*
                 * Redirect the channel to write syscall error messages to
@@ -401,16 +403,6 @@ int start_command(struct child_process *cmd)
                                        unsetenv(*cmd->env);
                        }
                }
-               if (cmd->preexec_cb) {
-                       /*
-                        * We cannot predict what the pre-exec callback does.
-                        * Forgo parent notification.
-                        */
-                       close(child_notifier);
-                       child_notifier = -1;
-
-                       cmd->preexec_cb();
-               }
                if (cmd->git_cmd) {
                        execv_git_cmd(cmd->argv);
                } else if (cmd->use_shell) {
@@ -429,7 +421,7 @@ int start_command(struct child_process *cmd)
        }
        if (cmd->pid < 0)
                error("cannot fork() for %s: %s", cmd->argv[0],
-                       strerror(failed_errno = errno));
+                       strerror(errno));
        else if (cmd->clean_on_exit)
                mark_child_for_cleanup(cmd->pid);
 
@@ -446,8 +438,7 @@ int start_command(struct child_process *cmd)
                 * 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],
-                             cmd->silent_exec_failure);
+               wait_or_whine(cmd->pid, cmd->argv[0]);
                failed_errno = errno;
                cmd->pid = -1;
        }
@@ -552,7 +543,7 @@ int start_command(struct child_process *cmd)
 
 int finish_command(struct child_process *cmd)
 {
-       return wait_or_whine(cmd->pid, cmd->argv[0], cmd->silent_exec_failure);
+       return wait_or_whine(cmd->pid, cmd->argv[0]);
 }
 
 int run_command(struct child_process *cmd)
@@ -597,6 +588,7 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const
 static pthread_t main_thread;
 static int main_thread_set;
 static pthread_key_t async_key;
+static pthread_key_t async_die_counter;
 
 static void *run_thread(void *data)
 {
@@ -623,6 +615,14 @@ static NORETURN void die_async(const char *err, va_list params)
 
        exit(128);
 }
+
+static int async_die_is_recursing(void)
+{
+       void *ret = pthread_getspecific(async_die_counter);
+       pthread_setspecific(async_die_counter, (void *)1);
+       return ret != NULL;
+}
+
 #endif
 
 int start_async(struct async *async)
@@ -704,7 +704,9 @@ int start_async(struct async *async)
                main_thread_set = 1;
                main_thread = pthread_self();
                pthread_key_create(&async_key, NULL);
+               pthread_key_create(&async_die_counter, NULL);
                set_die_routine(die_async);
+               set_die_is_recursing_routine(async_die_is_recursing);
        }
 
        if (proc_in >= 0)
@@ -739,7 +741,7 @@ int start_async(struct async *async)
 int finish_async(struct async *async)
 {
 #ifdef NO_PTHREADS
-       return wait_or_whine(async->pid, "child process", 0);
+       return wait_or_whine(async->pid, "child process");
 #else
        void *ret = (void *)(intptr_t)(-1);
 
@@ -749,6 +751,15 @@ int finish_async(struct async *async)
 #endif
 }
 
+char *find_hook(const char *name)
+{
+       char *path = git_path("hooks/%s", name);
+       if (access(path, X_OK) < 0)
+               path = NULL;
+
+       return path;
+}
+
 int run_hook(const char *index_file, const char *name, ...)
 {
        struct child_process hook;
@@ -758,11 +769,13 @@ int run_hook(const char *index_file, const char *name, ...)
        va_list args;
        int ret;
 
-       if (access(git_path("hooks/%s", name), X_OK) < 0)
+       p = find_hook(name);
+       if (!p)
                return 0;
 
+       argv_array_push(&argv, p);
+
        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);