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 <bmw...@google.com>
---
 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

Reply via email to