@@ -441,7 +441,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
441441static int do_stat_internal (int follow , const char * file_name , struct stat * buf )
442442{
443443 int namelen ;
444- static char alt_name [PATH_MAX ];
444+ char alt_name [PATH_MAX ];
445445
446446 if (!do_lstat (follow , file_name , buf ))
447447 return 0 ;
@@ -831,9 +831,10 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
831831 const char * dir ,
832832 int prepend_cmd , int fhin , int fhout , int fherr )
833833{
834- STARTUPINFO si ;
834+ STARTUPINFOW si ;
835835 PROCESS_INFORMATION pi ;
836836 struct strbuf envblk , args ;
837+ wchar_t wcmd [MAX_PATH ], wdir [MAX_PATH ], * wargs ;
837838 unsigned flags ;
838839 BOOL ret ;
839840
@@ -869,6 +870,11 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
869870 si .hStdOutput = winansi_get_osfhandle (fhout );
870871 si .hStdError = winansi_get_osfhandle (fherr );
871872
873+ if (xutftowcs_path (wcmd , cmd ) < 0 )
874+ return -1 ;
875+ if (dir && xutftowcs_path (wdir , dir ) < 0 )
876+ return -1 ;
877+
872878 /* concatenate argv, quoting args as we go */
873879 strbuf_init (& args , 0 );
874880 if (prepend_cmd ) {
@@ -886,6 +892,10 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
886892 free (quoted );
887893 }
888894
895+ wargs = xmalloc ((2 * args .len + 1 ) * sizeof (wchar_t ));
896+ xutftowcs (wargs , args .buf , 2 * args .len + 1 );
897+ strbuf_release (& args );
898+
889899 if (env ) {
890900 int count = 0 ;
891901 char * * e , * * sorted_env ;
@@ -907,12 +917,12 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
907917 }
908918
909919 memset (& pi , 0 , sizeof (pi ));
910- ret = CreateProcess ( cmd , args . buf , NULL , NULL , TRUE, flags ,
911- env ? envblk .buf : NULL , dir , & si , & pi );
920+ ret = CreateProcessW ( wcmd , wargs , NULL , NULL , TRUE, flags ,
921+ env ? envblk .buf : NULL , dir ? wdir : NULL , & si , & pi );
912922
913923 if (env )
914924 strbuf_release (& envblk );
915- strbuf_release ( & args );
925+ free ( wargs );
916926
917927 if (!ret ) {
918928 errno = ENOENT ;
@@ -941,10 +951,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
941951 return (pid_t )pi .dwProcessId ;
942952}
943953
944- static pid_t mingw_spawnve (const char * cmd , const char * * argv , char * * env ,
945- int prepend_cmd )
954+ static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
946955{
947- return mingw_spawnve_fd (cmd , argv , env , NULL , prepend_cmd , 0 , 1 , 2 );
956+ return mingw_spawnve_fd (cmd , argv , environ , NULL , prepend_cmd , 0 , 1 , 2 );
948957}
949958
950959pid_t mingw_spawnvpe (const char * cmd , const char * * argv , char * * env ,
@@ -986,7 +995,7 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
986995 return pid ;
987996}
988997
989- static int try_shell_exec (const char * cmd , char * const * argv , char * * env )
998+ static int try_shell_exec (const char * cmd , char * const * argv )
990999{
9911000 const char * interpr = parse_interpreter (cmd );
9921001 char * * path ;
@@ -1004,7 +1013,7 @@ static int try_shell_exec(const char *cmd, char *const *argv, char **env)
10041013 argv2 = xmalloc (sizeof (* argv ) * (argc + 1 ));
10051014 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
10061015 memcpy (& argv2 [1 ], & argv [1 ], sizeof (* argv ) * argc );
1007- pid = mingw_spawnve (prog , argv2 , env , 1 );
1016+ pid = mingw_spawnv (prog , argv2 , 1 );
10081017 if (pid >= 0 ) {
10091018 int status ;
10101019 if (waitpid (pid , & status , 0 ) < 0 )
@@ -1019,19 +1028,20 @@ static int try_shell_exec(const char *cmd, char *const *argv, char **env)
10191028 return pid ;
10201029}
10211030
1022- static void mingw_execve (const char * cmd , char * const * argv , char * const * env )
1031+ int mingw_execv (const char * cmd , char * const * argv )
10231032{
10241033 /* check if git_command is a shell script */
1025- if (!try_shell_exec (cmd , argv , ( char * * ) env )) {
1034+ if (!try_shell_exec (cmd , argv )) {
10261035 int pid , status ;
10271036
1028- pid = mingw_spawnve (cmd , (const char * * )argv , ( char * * ) env , 0 );
1037+ pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
10291038 if (pid < 0 )
1030- return ;
1039+ return -1 ;
10311040 if (waitpid (pid , & status , 0 ) < 0 )
10321041 status = 255 ;
10331042 exit (status );
10341043 }
1044+ return -1 ;
10351045}
10361046
10371047int mingw_execvp (const char * cmd , char * const * argv )
@@ -1040,7 +1050,7 @@ int mingw_execvp(const char *cmd, char *const *argv)
10401050 char * prog = path_lookup (cmd , path , 0 );
10411051
10421052 if (prog ) {
1043- mingw_execve (prog , argv , environ );
1053+ mingw_execv (prog , argv );
10441054 free (prog );
10451055 } else
10461056 errno = ENOENT ;
@@ -1049,12 +1059,6 @@ int mingw_execvp(const char *cmd, char *const *argv)
10491059 return -1 ;
10501060}
10511061
1052- int mingw_execv (const char * cmd , char * const * argv )
1053- {
1054- mingw_execve (cmd , argv , environ );
1055- return -1 ;
1056- }
1057-
10581062int mingw_kill (pid_t pid , int sig )
10591063{
10601064 if (pid > 0 && sig == SIGTERM ) {
@@ -1933,10 +1937,54 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen)
19331937 return -1 ;
19341938}
19351939
1940+ /*
1941+ * Disable MSVCRT command line wildcard expansion (__getmainargs called from
1942+ * mingw startup code, see init.c in mingw runtime).
1943+ */
1944+ int _CRT_glob = 0 ;
1945+
1946+ typedef struct {
1947+ int newmode ;
1948+ } _startupinfo ;
1949+
1950+ extern int __wgetmainargs (int * argc , wchar_t * * * argv , wchar_t * * * env , int glob ,
1951+ _startupinfo * si );
1952+
1953+ static NORETURN void die_startup ()
1954+ {
1955+ fputs ("fatal: not enough memory for initialization" , stderr );
1956+ exit (128 );
1957+ }
1958+
19361959void mingw_startup ()
19371960{
1938- /* copy executable name to argv[0] */
1939- __argv [0 ] = xstrdup (_pgmptr );
1961+ int i , len , maxlen , argc ;
1962+ char * buffer ;
1963+ wchar_t * * wenv , * * wargv ;
1964+ _startupinfo si ;
1965+
1966+ /* get wide char arguments and environment */
1967+ si .newmode = 0 ;
1968+ if (__wgetmainargs (& argc , & wargv , & wenv , _CRT_glob , & si ) < 0 )
1969+ die_startup ();
1970+
1971+ /* determine size of argv and environ conversion buffer */
1972+ maxlen = wcslen (_wpgmptr );
1973+ for (i = 1 ; i < argc ; i ++ )
1974+ maxlen = max (maxlen , wcslen (wargv [i ]));
1975+
1976+ /* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
1977+ maxlen = 3 * maxlen + 1 ;
1978+ buffer = xmalloc (maxlen );
1979+
1980+ /* convert command line arguments and environment to UTF-8 */
1981+ len = xwcstoutf (buffer , _wpgmptr , maxlen );
1982+ __argv [0 ] = xmemdupz (buffer , len );
1983+ for (i = 1 ; i < argc ; i ++ ) {
1984+ len = xwcstoutf (buffer , wargv [i ], maxlen );
1985+ __argv [i ] = xmemdupz (buffer , len );
1986+ }
1987+ free (buffer );
19401988
19411989 /* initialize critical section for waitpid pinfo_t list */
19421990 InitializeCriticalSection (& pinfo_cs );
0 commit comments