In order to avoid allocation between 'fork()' and 'exec()' open the stream used for the child's error handeling prior to forking. Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> --- run-command.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/run-command.c b/run-command.c index 2514b54bc..029d41463 100644 --- a/run-command.c +++ b/run-command.c @@ -365,11 +365,18 @@ int start_command(struct child_process *cmd) #ifndef GIT_WINDOWS_NATIVE { int notify_pipe[2]; + FILE *child_err = NULL; struct argv_array argv = ARGV_ARRAY_INIT; if (pipe(notify_pipe)) notify_pipe[0] = notify_pipe[1] = -1; + if (cmd->no_stderr || need_err) { + int child_err_fd = dup(2); + set_cloexec(child_err_fd); + child_err = fdopen(child_err_fd, "w"); + } + if (cmd->git_cmd) { argv_array_push(&argv, "git"); argv_array_pushv(&argv, cmd->argv); @@ -387,11 +394,8 @@ int start_command(struct child_process *cmd) * before redirecting the process's stderr so that all die() * in subsequent call paths use the parent's stderr. */ - if (cmd->no_stderr || need_err) { - int child_err = dup(2); - set_cloexec(child_err); - set_error_handle(fdopen(child_err, "w")); - } + if (child_err) + set_error_handle(child_err); close(notify_pipe[0]); set_cloexec(notify_pipe[1]); @@ -477,6 +481,8 @@ int start_command(struct child_process *cmd) } close(notify_pipe[0]); + if (child_err) + fclose(child_err); argv_array_clear(&argv); } #else -- 2.12.2.715.g7642488e1d-goog