From 570f1e6e1a7145efb4e80da9c711fcbc319f6b17 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 28 May 2012 21:21:39 -0500 Subject: Win32: let mingw_execve() return an int This is in the great tradition of POSIX. Original fix by Olivier Refalo. Signed-off-by: Johannes Schindelin Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index d242557eb5..7da73fa617 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1019,7 +1019,7 @@ static int try_shell_exec(const char *cmd, char *const *argv, char **env) return pid; } -static void mingw_execve(const char *cmd, char *const *argv, char *const *env) +static int 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, (char **)env)) { @@ -1027,11 +1027,12 @@ static void mingw_execve(const char *cmd, char *const *argv, char *const *env) pid = mingw_spawnve(cmd, (const char **)argv, (char **)env, 0); if (pid < 0) - return; + return -1; if (waitpid(pid, &status, 0) < 0) status = 255; exit(status); } + return -1; } int mingw_execvp(const char *cmd, char *const *argv) -- cgit v1.2.3 From 3e66e47b1b1baef859be79a12091fdbdd82492a8 Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Fri, 25 Nov 2011 21:33:17 +0100 Subject: Win32: simplify internal mingw_spawn* APIs The only public spawn function that needs to tweak the environment is mingw_spawnvpe (called from start_command). Nevertheless, all internal spawn* functions take an env parameter and needlessly pass the global char **environ around. Remove the env parameter where it's not needed. This removes the internal mingw_execve abstraction, which is no longer needed. Signed-off-by: Karsten Blees Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 7da73fa617..1c0b1531b8 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -941,10 +941,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, return (pid_t)pi.dwProcessId; } -static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, - int prepend_cmd) +static pid_t mingw_spawnv(const char *cmd, const char **argv, int prepend_cmd) { - return mingw_spawnve_fd(cmd, argv, env, NULL, prepend_cmd, 0, 1, 2); + return mingw_spawnve_fd(cmd, argv, environ, NULL, prepend_cmd, 0, 1, 2); } pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, @@ -986,7 +985,7 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, return pid; } -static int try_shell_exec(const char *cmd, char *const *argv, char **env) +static int try_shell_exec(const char *cmd, char *const *argv) { const char *interpr = parse_interpreter(cmd); char **path; @@ -1004,7 +1003,7 @@ static int try_shell_exec(const char *cmd, char *const *argv, char **env) argv2 = xmalloc(sizeof(*argv) * (argc+1)); argv2[0] = (char *)cmd; /* full path to the script file */ memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc); - pid = mingw_spawnve(prog, argv2, env, 1); + pid = mingw_spawnv(prog, argv2, 1); if (pid >= 0) { int status; if (waitpid(pid, &status, 0) < 0) @@ -1019,13 +1018,13 @@ static int try_shell_exec(const char *cmd, char *const *argv, char **env) return pid; } -static int mingw_execve(const char *cmd, char *const *argv, char *const *env) +int mingw_execv(const char *cmd, char *const *argv) { /* check if git_command is a shell script */ - if (!try_shell_exec(cmd, argv, (char **)env)) { + if (!try_shell_exec(cmd, argv)) { int pid, status; - pid = mingw_spawnve(cmd, (const char **)argv, (char **)env, 0); + pid = mingw_spawnv(cmd, (const char **)argv, 0); if (pid < 0) return -1; if (waitpid(pid, &status, 0) < 0) @@ -1041,7 +1040,7 @@ int mingw_execvp(const char *cmd, char *const *argv) char *prog = path_lookup(cmd, path, 0); if (prog) { - mingw_execve(prog, argv, environ); + mingw_execv(prog, argv); free(prog); } else errno = ENOENT; @@ -1050,12 +1049,6 @@ int mingw_execvp(const char *cmd, char *const *argv) return -1; } -int mingw_execv(const char *cmd, char *const *argv) -{ - mingw_execve(cmd, argv, environ); - return -1; -} - int mingw_kill(pid_t pid, int sig) { if (pid > 0 && sig == SIGTERM) { -- cgit v1.2.3 From 58aa3d2a69ded1f48a1c9c63176384d02925c9d6 Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Fri, 7 Jan 2011 18:04:16 +0100 Subject: Win32: fix potential multi-threading issue ...by removing a static buffer in do_stat_internal. Signed-off-by: Karsten Blees Signed-off-by: Erik Faye-Lund Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/mingw.c b/compat/mingw.c index 1c0b1531b8..6849815b39 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -441,7 +441,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf) static int do_stat_internal(int follow, const char *file_name, struct stat *buf) { int namelen; - static char alt_name[PATH_MAX]; + char alt_name[PATH_MAX]; if (!do_lstat(follow, file_name, buf)) return 0; -- cgit v1.2.3 From 5901dc6613fcb5e4a4c49e09992a13a4840edb48 Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Fri, 7 Jan 2011 19:52:20 +0100 Subject: MinGW: disable CRT command line globbing MingwRT listens to _CRT_glob to decide if __getmainargs should perform globbing, with the default being that it should. Unfortunately, __getmainargs globbing is sub-par; for instance patterns like "*.c" will only match c-sources in the current directory. Disable __getmainargs' command line wildcard expansion, so these patterns will be left untouched, and handled by Git's superior built-in globbing instead. MSVC defaults to no globbing, so we don't need to do anything in that case. This fixes t5505 and t7810. Signed-off-by: Karsten Blees Signed-off-by: Erik Faye-Lund Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compat/mingw.c b/compat/mingw.c index 6849815b39..1140a131bf 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1927,6 +1927,12 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) return -1; } +/* + * Disable MSVCRT command line wildcard expansion (__getmainargs called from + * mingw startup code, see init.c in mingw runtime). + */ +int _CRT_glob = 0; + void mingw_startup() { /* copy executable name to argv[0] */ -- cgit v1.2.3 From 99c3c76d97164dba2cdd288281a0121de46f11e3 Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Sun, 16 Jan 2011 18:27:53 +0100 Subject: Win32: Unicode arguments (outgoing) Convert command line arguments from UTF-8 to UTF-16 when creating other processes. Signed-off-by: Karsten Blees Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 1140a131bf..8a7b0476c2 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -831,9 +831,10 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, const char *dir, int prepend_cmd, int fhin, int fhout, int fherr) { - STARTUPINFO si; + STARTUPINFOW si; PROCESS_INFORMATION pi; struct strbuf envblk, args; + wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs; unsigned flags; BOOL ret; @@ -869,6 +870,11 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, si.hStdOutput = winansi_get_osfhandle(fhout); si.hStdError = winansi_get_osfhandle(fherr); + if (xutftowcs_path(wcmd, cmd) < 0) + return -1; + if (dir && xutftowcs_path(wdir, dir) < 0) + return -1; + /* concatenate argv, quoting args as we go */ strbuf_init(&args, 0); if (prepend_cmd) { @@ -886,6 +892,10 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, free(quoted); } + wargs = xmalloc((2 * args.len + 1) * sizeof(wchar_t)); + xutftowcs(wargs, args.buf, 2 * args.len + 1); + strbuf_release(&args); + if (env) { int count = 0; char **e, **sorted_env; @@ -907,12 +917,12 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, } memset(&pi, 0, sizeof(pi)); - ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags, - env ? envblk.buf : NULL, dir, &si, &pi); + ret = CreateProcessW(wcmd, wargs, NULL, NULL, TRUE, flags, + env ? envblk.buf : NULL, dir ? wdir : NULL, &si, &pi); if (env) strbuf_release(&envblk); - strbuf_release(&args); + free(wargs); if (!ret) { errno = ENOENT; -- cgit v1.2.3 From 3f046148d92e1aa6c0872a6f11f39a4a5740f939 Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Sun, 16 Jan 2011 18:28:27 +0100 Subject: Win32: Unicode arguments (incoming) Convert command line arguments from UTF-16 to UTF-8 on startup. Signed-off-by: Karsten Blees Signed-off-by: Stepan Kasal Signed-off-by: Junio C Hamano --- compat/mingw.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 8a7b0476c2..3baaa4dfae 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1943,10 +1943,48 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) */ int _CRT_glob = 0; +typedef struct { + int newmode; +} _startupinfo; + +extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob, + _startupinfo *si); + +static NORETURN void die_startup() +{ + fputs("fatal: not enough memory for initialization", stderr); + exit(128); +} + void mingw_startup() { - /* copy executable name to argv[0] */ - __argv[0] = xstrdup(_pgmptr); + int i, len, maxlen, argc; + char *buffer; + wchar_t **wenv, **wargv; + _startupinfo si; + + /* get wide char arguments and environment */ + si.newmode = 0; + if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0) + die_startup(); + + /* determine size of argv and environ conversion buffer */ + maxlen = wcslen(_wpgmptr); + for (i = 1; i < argc; i++) + maxlen = max(maxlen, wcslen(wargv[i])); + + /* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */ + maxlen = 3 * maxlen + 1; + buffer = xmalloc(maxlen); + + /* convert command line arguments and environment to UTF-8 */ + len = xwcstoutf(buffer, _wpgmptr, maxlen); + __argv[0] = xmemdupz(buffer, len); + for (i = 1; i < argc; i++) { + len = xwcstoutf(buffer, wargv[i], maxlen); + __argv[i] = xmemdupz(buffer, len); + } + free(buffer); /* initialize critical section for waitpid pinfo_t list */ InitializeCriticalSection(&pinfo_cs); -- cgit v1.2.3