diff options
-rw-r--r-- | git.c | 1 | ||||
-rw-r--r-- | run-command.c | 19 | ||||
-rw-r--r-- | run-command.h | 1 |
3 files changed, 21 insertions, 0 deletions
@@ -588,6 +588,7 @@ static void execv_dashed_external(const char **argv) argv_array_pushf(&cmd.args, "git-%s", argv[0]); argv_array_pushv(&cmd.args, argv + 1); cmd.clean_on_exit = 1; + cmd.wait_after_clean = 1; cmd.silent_exec_failure = 1; trace_argv_printf(cmd.args.argv, "trace: exec:"); diff --git a/run-command.c b/run-command.c index ca905a9e80..73bfba7ef9 100644 --- a/run-command.c +++ b/run-command.c @@ -29,6 +29,8 @@ static int installed_child_cleanup_handler; static void cleanup_children(int sig, int in_signal) { + struct child_to_clean *children_to_wait_for = NULL; + while (children_to_clean) { struct child_to_clean *p = children_to_clean; children_to_clean = p->next; @@ -45,6 +47,23 @@ static void cleanup_children(int sig, int in_signal) } kill(p->pid, sig); + + if (p->process->wait_after_clean) { + p->next = children_to_wait_for; + children_to_wait_for = p; + } else { + if (!in_signal) + free(p); + } + } + + while (children_to_wait_for) { + struct child_to_clean *p = children_to_wait_for; + children_to_wait_for = p->next; + + while (waitpid(p->pid, NULL, 0) < 0 && errno == EINTR) + ; /* spin waiting for process exit or error */ + if (!in_signal) free(p); } diff --git a/run-command.h b/run-command.h index dd1c78c28d..4fa8f65adb 100644 --- a/run-command.h +++ b/run-command.h @@ -43,6 +43,7 @@ struct child_process { unsigned stdout_to_stderr:1; unsigned use_shell:1; unsigned clean_on_exit:1; + unsigned wait_after_clean:1; void (*clean_on_exit_handler)(struct child_process *process); void *clean_on_exit_handler_cbdata; }; |