Web lists-archives.com

[PATCH 3/5] run-command: allocate child_err before forking




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