add tests for rebasing root
[gitweb.git] / run-command.c
index 12d4ddb552204ba010ac90f24429d81a74e78a4e..1b32a12a29b64fcc7d8b2401b00fb8a70ff81bad 100644 (file)
@@ -273,7 +273,8 @@ 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;
 
        /*
         * In case of errors we must keep the promise to close FDs
@@ -286,6 +287,7 @@ int start_command(struct child_process *cmd)
                        failed_errno = errno;
                        if (cmd->out > 0)
                                close(cmd->out);
+                       str = "standard input";
                        goto fail_pipe;
                }
                cmd->in = fdin[1];
@@ -301,6 +303,7 @@ int start_command(struct child_process *cmd)
                                close_pair(fdin);
                        else if (cmd->in)
                                close(cmd->in);
+                       str = "standard output";
                        goto fail_pipe;
                }
                cmd->out = fdout[0];
@@ -318,9 +321,10 @@ int start_command(struct child_process *cmd)
                                close_pair(fdout);
                        else if (cmd->out)
                                close(cmd->out);
+                       str = "standard error";
 fail_pipe:
-                       error("cannot create pipe for %s: %s",
-                               cmd->argv[0], strerror(failed_errno));
+                       error("cannot create %s pipe for %s: %s",
+                               str, cmd->argv[0], strerror(failed_errno));
                        errno = failed_errno;
                        return -1;
                }
@@ -337,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
@@ -416,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);
 
@@ -583,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)
 {
@@ -609,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)
@@ -690,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)