diff --git a/compat/mingw.c b/compat/mingw.c index 850ee2ad5c..6d2e518256 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -407,14 +407,14 @@ static const char *quote_arg(const char *arg) return q; } -void quote_argv(const char **dst, const char *const *src) +static void quote_argv(const char **dst, const char *const *src) { while (*src) *dst++ = quote_arg(*src++); *dst = NULL; } -const char *parse_interpreter(const char *cmd) +static const char *parse_interpreter(const char *cmd) { static char buf[100]; char *p, *opt; @@ -452,7 +452,7 @@ const char *parse_interpreter(const char *cmd) /* * Splits the PATH into parts. */ -char **mingw_get_path_split(void) +static char **mingw_get_path_split(void) { char *p, **path, *envpath = getenv("PATH"); int i, n = 0; @@ -488,7 +488,7 @@ char **mingw_get_path_split(void) return path; } -void mingw_free_path_split(char **path) +static void mingw_free_path_split(char **path) { if (!path) return; @@ -516,7 +516,7 @@ static char *lookup_prog(const char *dir, const char *cmd, int tryexe) * Determines the absolute path of cmd using the the split path in path. * If cmd contains a slash or backslash, no lookup is performed. */ -char *mingw_path_lookup(const char *cmd, char **path) +static char *mingw_path_lookup(const char *cmd, char **path) { char **p = path; char *prog = NULL; @@ -537,6 +537,35 @@ char *mingw_path_lookup(const char *cmd, char **path) return prog; } +pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env) +{ + pid_t pid; + char **path = mingw_get_path_split(); + const char **qargv; + char *prog = mingw_path_lookup(cmd, path); + const char *interpr = parse_interpreter(prog); + int argc; + + for (argc = 0; argv[argc];) argc++; + qargv = xmalloc((argc+2)*sizeof(char*)); + if (!interpr) { + quote_argv(qargv, argv); + pid = spawnve(_P_NOWAIT, prog, qargv, (const char **)env); + } else { + qargv[0] = interpr; + qargv[1] = quote_arg(prog); + quote_argv(&qargv[2], &argv[1]); + pid = spawnvpe(_P_NOWAIT, interpr, qargv, (const char **)env); + } + + free(qargv); /* TODO: quoted args should be freed, too */ + free(prog); + + mingw_free_path_split(path); + + return pid; +} + static int try_shell_exec(const char *cmd, char *const *argv, char *const *env) { const char **sh_argv; @@ -562,7 +591,7 @@ static int try_shell_exec(const char *cmd, char *const *argv, char *const *env) exit(n); } -void mingw_execve(const char *cmd, char *const *argv, char *const *env) +static void mingw_execve(const char *cmd, char *const *argv, char *const *env) { /* check if git_command is a shell script */ if (!try_shell_exec(cmd, argv, env)) { diff --git a/git-compat-util.h b/git-compat-util.h index 31d43152d2..5235d31f27 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -470,11 +470,10 @@ static inline int kill(pid_t pid, int sig) static inline unsigned int alarm(unsigned int seconds) { return 0; } -void mingw_execve(const char *cmd, char *const *argv, char * const *env); -#define execve mingw_execve +typedef int pid_t; +extern pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env); extern void mingw_execvp(const char *cmd, char *const *argv); #define execvp mingw_execvp -typedef int pid_t; static inline int waitpid(pid_t pid, unsigned *status, unsigned options) { if (options == 0) @@ -552,12 +551,6 @@ static inline int getppid(void) { return 1; } static inline void sync(void) {} extern int getpagesize(void); /* defined in MinGW's libgcc.a */ -extern void quote_argv(const char **dst, const char *const *src); -extern const char *parse_interpreter(const char *cmd); -extern char *mingw_path_lookup(const char *cmd, char **path); -extern char **mingw_get_path_split(void); -extern void mingw_free_path_split(char **path); - /* Use mingw_lstat() instead of lstat()/stat() and * mingw_fstat() instead of fstat() on Windows. * struct stat is redefined because it lacks the st_blocks member. diff --git a/run-command.c b/run-command.c index 05934f708f..cf1377de64 100644 --- a/run-command.c +++ b/run-command.c @@ -160,29 +160,8 @@ int start_command(struct child_process *cmd) cmd->argv[0] = git_cmd.buf; } - char **path = mingw_get_path_split(); - const char *argv0 = cmd->argv[0]; - const char **qargv; - char *prog = mingw_path_lookup(argv0, path); - const char *interpr = parse_interpreter(prog); - int argc; + cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env); - for (argc = 0; cmd->argv[argc];) argc++; - qargv = xmalloc((argc+2)*sizeof(char*)); - if (!interpr) { - quote_argv(qargv, cmd->argv); - cmd->pid = spawnve(_P_NOWAIT, prog, qargv, (const char **)env); - } else { - qargv[0] = interpr; - cmd->argv[0] = prog; - quote_argv(&qargv[1], cmd->argv); - cmd->pid = spawnvpe(_P_NOWAIT, interpr, qargv, (const char **)env); - } - - free(qargv); /* TODO: quoted args should be freed, too */ - free(prog); - - mingw_free_path_split(path); /* TODO: if (cmd->env) free env; */ if (cmd->git_cmd)