[PATCH 18/40] Windows: Implement start_command().

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Johannes Sixt
Date: Wednesday, February 27, 2008 - 11:54 am

On Windows, we have spawnv() variants to run a child process instead of
fork()/exec(). In order to attach pipe ends to stdin, stdout, and stderr,
we have to use this idiom:

    save1 = dup(1);
    dup2(pipe[1], 1);
    spawnv();
    dup2(save1, 1);
    close(pipe[1]);

assuming that the descriptors created by pipe() are not inheritable.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 git-compat-util.h |    8 +++++
 run-command.c     |   89 +++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index 170c279..046891d 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -608,6 +608,14 @@ void mingw_execvp(const char *cmd, char *const *argv);
 sig_handler_t mingw_signal(int sig, sig_handler_t handler);
 #define signal mingw_signal
 
+/*
+ * helpers
+ */
+
+char **copy_environ(void);
+void free_environ(char **env);
+char **env_setenv(char **env, const char *name);
+
 #endif /* __MINGW32__ */
 
 #endif
diff --git a/run-command.c b/run-command.c
index 476d00c..873f6d0 100644
--- a/run-command.c
+++ b/run-command.c
@@ -53,17 +53,8 @@ int start_command(struct child_process *cmd)
 		cmd->err = fderr[0];
 	}
 
+#ifndef __MINGW32__
 	cmd->pid = fork();
-	if (cmd->pid < 0) {
-		if (need_in)
-			close_pair(fdin);
-		if (need_out)
-			close_pair(fdout);
-		if (need_err)
-			close_pair(fderr);
-		return -ERR_RUN_COMMAND_FORK;
-	}
-
 	if (!cmd->pid) {
 		if (cmd->no_stdin)
 			dup_devnull(0);
@@ -112,6 +103,84 @@ int start_command(struct child_process *cmd)
 		}
 		die("exec %s failed.", cmd->argv[0]);
 	}
+#else
+	int s0 = -1, s1 = -1, s2 = -1;	/* backups of stdin, stdout, stderr */
+	const char *sargv0 = cmd->argv[0];
+	char **env = environ;
+	struct strbuf git_cmd;
+
+	if (cmd->no_stdin) {
+		s0 = dup(0);
+		dup_devnull(0);
+	} else if (need_in) {
+		s0 = dup(0);
+		dup2(fdin[0], 0);
+	} else if (cmd->in) {
+		s0 = dup(0);
+		dup2(cmd->in, 0);
+	}
+
+	if (cmd->no_stdout) {
+		s1 = dup(1);
+		dup_devnull(1);
+	} else if (cmd->stdout_to_stderr) {
+		s1 = dup(1);
+		dup2(2, 1);
+	} else if (need_out) {
+		s1 = dup(1);
+		dup2(fdout[1], 1);
+	} else if (cmd->out > 1) {
+		s1 = dup(1);
+		dup2(cmd->out, 1);
+	}
+
+	if (cmd->no_stderr) {
+		s2 = dup(2);
+		dup_devnull(2);
+	} else if (need_err) {
+		s2 = dup(2);
+		dup2(fderr[1], 2);
+	}
+
+	if (cmd->dir)
+		die("chdir in start_command() not implemented");
+	if (cmd->env) {
+		env = copy_environ();
+		for (; *cmd->env; cmd->env++)
+			env = env_setenv(env, *cmd->env);
+	}
+
+	if (cmd->git_cmd) {
+		strbuf_init(&git_cmd, 0);
+		strbuf_addf(&git_cmd, "git-%s", cmd->argv[0]);
+		cmd->argv[0] = git_cmd.buf;
+	}
+
+	cmd->pid = spawnvpe(_P_NOWAIT, cmd->argv[0], cmd->argv, (const char **)env);
+
+	if (cmd->env)
+		free_environ(env);
+	if (cmd->git_cmd)
+		strbuf_release(&git_cmd);
+
+	cmd->argv[0] = sargv0;
+	if (s0 >= 0)
+		dup2(s0, 0), close(s0);
+	if (s1 >= 0)
+		dup2(s1, 1), close(s1);
+	if (s2 >= 0)
+		dup2(s2, 2), close(s2);
+#endif
+
+	if (cmd->pid < 0) {
+		if (need_in)
+			close_pair(fdin);
+		if (need_out)
+			close_pair(fdout);
+		if (need_err)
+			close_pair(fderr);
+		return -ERR_RUN_COMMAND_FORK;
+	}
 
 	if (need_in)
 		close(fdin[0]);
-- 
1.5.4.1.126.ge5a7d

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 00/40] MinGW port, Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 02/40] Compile some programs only conditionally., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 09/40] Windows: Work around misbehaved rename()., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 10/40] Windows: Treat Windows style path names., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 12/40] Windows: Implement gettimeofday()., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 13/40] Windows: Fix PRIuMAX definition., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 18/40] Windows: Implement start_command()., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 20/40] Windows: A rudimentary poll() emulation., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 27/40] Windows: Implement a custom spawnve()., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 30/40] Turn builtin_exec_path into a function., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 34/40] Windows: Make the pager work., Johannes Sixt, (Wed Feb 27, 11:54 am)
[PATCH 37/40] Windows: Make 'git help -a' work., Johannes Sixt, (Wed Feb 27, 11:55 am)
Re: [PATCH 00/40] MinGW port, Marius Storm-Olsen, (Wed Feb 27, 3:01 pm)
Re: [PATCH 00/40] MinGW port, Martin Langhoff, (Wed Feb 27, 4:34 pm)
Re: [PATCH 01/40] Add compat/regex.[ch] and compat/fnmatch ..., Johannes Schindelin, (Wed Feb 27, 4:43 pm)
Re: [PATCH 00/40] MinGW port, Johannes Schindelin, (Wed Feb 27, 4:58 pm)
Re: [PATCH 00/40] MinGW port, Nguyen Thai Ngoc Duy, (Wed Feb 27, 8:38 pm)
Re: [PATCH 37/40] Windows: Make 'git help -a' work., Paolo Bonzini, (Thu Feb 28, 2:52 am)
Re: [PATCH 02/40] Compile some programs only conditionally., Johannes Schindelin, (Thu Feb 28, 4:57 am)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Thu Feb 28, 5:05 am)
Re: [PATCH 08/40] Windows: always chmod(, 0666) before unl ..., Johannes Schindelin, (Thu Feb 28, 5:09 am)
Re: [PATCH 10/40] Windows: Treat Windows style path names., Johannes Schindelin, (Thu Feb 28, 5:18 am)
Re: [PATCH 13/40] Windows: Fix PRIuMAX definition., Johannes Schindelin, (Thu Feb 28, 5:21 am)
Re: [PATCH 03/40] Add target architecture MinGW., Paolo Bonzini, (Thu Feb 28, 5:57 am)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Thu Feb 28, 7:56 am)
Re: [PATCH 19/40] Windows: Change the name of hook scripts ..., Johannes Schindelin, (Thu Feb 28, 8:20 am)
Re: [PATCH 21/40] Windows: Disambiguate DOS style paths fr ..., Johannes Schindelin, (Thu Feb 28, 8:22 am)
Re: [PATCH 22/40] Windows: Implement asynchronous function ..., Johannes Schindelin, (Thu Feb 28, 8:28 am)
Re: [PATCH 23/40] Windows: Local clone must use the drive ..., Johannes Schindelin, (Thu Feb 28, 8:31 am)
Re: [PATCH 27/40] Windows: Implement a custom spawnve()., Johannes Schindelin, (Thu Feb 28, 8:36 am)
Re: [PATCH 33/40] When installing, be prepared that templa ..., Johannes Schindelin, (Thu Feb 28, 8:45 am)
Re: [PATCH 40/40] compat/pread.c: Add foward decl to fix w ..., Johannes Schindelin, (Thu Feb 28, 8:51 am)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Thu Feb 28, 1:40 pm)
Re: [PATCH 13/40] Windows: Fix PRIuMAX definition., Johannes Sixt, (Thu Feb 28, 1:45 pm)
Re: [PATCH 27/40] Windows: Implement a custom spawnve()., Johannes Sixt, (Thu Feb 28, 2:04 pm)
Re: [PATCH 02/40] Compile some programs only conditionally., Johannes Schindelin, (Thu Feb 28, 5:47 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Thu Feb 28, 6:07 pm)
Re: [PATCH 04/40] Windows: Use the Windows style PATH sepa ..., Johannes Schindelin, (Thu Feb 28, 6:09 pm)
Re: [PATCH 19/40] Windows: Change the name of hook scripts ..., Johannes Schindelin, (Thu Feb 28, 6:11 pm)
Re: [PATCH 22/40] Windows: Implement asynchronous function ..., Johannes Schindelin, (Thu Feb 28, 6:17 pm)
Re: [PATCH 27/40] Windows: Implement a custom spawnve()., Johannes Schindelin, (Thu Feb 28, 6:18 pm)
Re: [PATCH 33/40] When installing, be prepared that templa ..., Johannes Schindelin, (Thu Feb 28, 6:21 pm)
Re: [PATCH 22/40] Windows: Implement asynchronous function ..., Johannes Schindelin, (Thu Feb 28, 6:27 pm)
Re: [PATCH 22/40] Windows: Implement asynchronous function ..., Johannes Schindelin, (Thu Feb 28, 6:54 pm)
Re: [PATCH 22/40] Windows: Implement asynchronous function ..., Johannes Schindelin, (Fri Feb 29, 3:26 am)
Re: [PATCH 04/40] Windows: Use the Windows style PATH sepa ..., Johannes Schindelin, (Fri Feb 29, 5:19 am)
Re: [PATCH 04/40] Windows: Use the Windows style PATH sepa ..., Johannes Schindelin, (Fri Feb 29, 5:59 am)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Fri Feb 29, 2:03 pm)
Re: [PATCH 02/40] Compile some programs only conditionally., Johannes Schindelin, (Fri Feb 29, 2:53 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Fri Feb 29, 2:54 pm)
Re: [PATCH 20/40] Windows: A rudimentary poll() emulation., Robin Rosenberg, (Sat Mar 1, 8:48 am)
Re: [PATCH 00/40] MinGW port, Johannes Sixt, (Sun Mar 2, 2:20 pm)
Re: [PATCH 00/40] MinGW port, Johannes Schindelin, (Sun Mar 2, 3:07 pm)
Re: [PATCH 00/40] MinGW port, Johannes Sixt, (Mon Mar 3, 11:34 am)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Wed Mar 5, 2:21 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Wed Mar 5, 3:18 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Junio C Hamano, (Wed Mar 5, 3:22 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Wed Mar 5, 3:28 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Junio C Hamano, (Wed Mar 5, 3:51 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Wed Mar 5, 5:11 pm)
[PATCH 1/2] Add strbuf_initf(), Johannes Schindelin, (Wed Mar 5, 6:14 pm)
[PATCH 2/2] format-patch: add --reviewed-by=&lt;ident&gt;, Johannes Schindelin, (Wed Mar 5, 6:15 pm)
Re: [PATCH 1/2] Add strbuf_initf(), Mike Hommey, (Wed Mar 5, 11:33 pm)
Re: [PATCH 1/2] Add strbuf_initf(), Reece Dunn, (Thu Mar 6, 2:03 am)
Re: [PATCH 2/2] format-patch: add --reviewed-by=&lt;ident&gt;, Johannes Schindelin, (Thu Mar 6, 3:40 am)
Re: [PATCH 1/2] Add strbuf_initf(), Johannes Schindelin, (Thu Mar 6, 3:53 am)
Re: [PATCH 1/2] Add strbuf_initf(), Johannes Schindelin, (Thu Mar 6, 3:55 am)
Re: [PATCH 1/2] Add strbuf_initf(), Reece Dunn, (Thu Mar 6, 4:53 am)
Re: [PATCH 1/2] Add strbuf_initf(), Jeff King, (Thu Mar 6, 5:09 am)
Re: [PATCH 1/2] Add strbuf_initf(), Johannes Schindelin, (Thu Mar 6, 5:52 am)
[PATCH 1/2 v2] Add strbuf_vaddf(), use it in strbuf_addf() ..., Johannes Schindelin, (Thu Mar 6, 9:29 am)
Re: [PATCH 1/2 v2] Add strbuf_vaddf(), use it in strbuf_ad ..., Johannes Schindelin, (Thu Mar 6, 9:59 am)
Re: [PATCH 1/2] Add strbuf_initf(), Kristian , (Thu Mar 6, 11:18 am)
Re: [PATCH 1/2] Add strbuf_initf(), Johannes Schindelin, (Thu Mar 6, 11:26 am)
Re: [PATCH 1/2] Add strbuf_initf(), Kristian , (Thu Mar 6, 11:35 am)
Re: [PATCH 1/2] Add strbuf_initf(), Mike Hommey, (Thu Mar 6, 12:10 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Thu Mar 6, 1:38 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Tue Mar 11, 2:30 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Tue Mar 11, 4:28 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Sixt, (Wed Mar 12, 3:59 pm)
Re: [PATCH 03/40] Add target architecture MinGW., Johannes Schindelin, (Wed Mar 12, 4:06 pm)