2323#include "../repository.h"
2424#include "win32/fscache.h"
2525#include "../attr.h"
26+ #include "../string-list.h"
2627
2728#define HCAST (type , handle ) ((type)(intptr_t)handle)
2829
@@ -1651,6 +1652,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16511652 return NULL ;
16521653}
16531654
1655+ static char * path_lookup (const char * cmd , int exe_only );
1656+
1657+ static char * is_busybox_applet (const char * cmd )
1658+ {
1659+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1660+ static char * busybox_path ;
1661+ static int busybox_path_initialized ;
1662+
1663+ /* Avoid infinite loop */
1664+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1665+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1666+ return NULL ;
1667+
1668+ if (!busybox_path_initialized ) {
1669+ busybox_path = path_lookup ("busybox.exe" , 1 );
1670+ busybox_path_initialized = 1 ;
1671+ }
1672+
1673+ /* Assume that sh is compiled in... */
1674+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1675+ return xstrdup_or_null (busybox_path );
1676+
1677+ if (!applets .nr ) {
1678+ struct child_process cp = CHILD_PROCESS_INIT ;
1679+ struct strbuf buf = STRBUF_INIT ;
1680+ char * p ;
1681+
1682+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1683+
1684+ if (capture_command (& cp , & buf , 2048 )) {
1685+ string_list_append (& applets , "" );
1686+ return NULL ;
1687+ }
1688+
1689+ /* parse output */
1690+ p = strstr (buf .buf , "Currently defined functions:\n" );
1691+ if (!p ) {
1692+ warning ("Could not parse output of busybox --help" );
1693+ string_list_append (& applets , "" );
1694+ return NULL ;
1695+ }
1696+ p = strchrnul (p , '\n' );
1697+ for (;;) {
1698+ size_t len ;
1699+
1700+ p += strspn (p , "\n\t ," );
1701+ len = strcspn (p , "\n\t ," );
1702+ if (!len )
1703+ break ;
1704+ p [len ] = '\0' ;
1705+ string_list_insert (& applets , p );
1706+ p = p + len + 1 ;
1707+ }
1708+ }
1709+
1710+ return string_list_has_string (& applets , cmd ) ?
1711+ xstrdup (busybox_path ) : NULL ;
1712+ }
1713+
16541714/*
16551715 * Determines the absolute path of cmd using the split path in path.
16561716 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1679,6 +1739,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16791739 path = sep + 1 ;
16801740 }
16811741
1742+ if (!prog && !isexe )
1743+ prog = is_busybox_applet (cmd );
1744+
16821745 return prog ;
16831746}
16841747
@@ -1882,8 +1945,8 @@ static int is_msys2_sh(const char *cmd)
18821945}
18831946
18841947static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1885- const char * dir ,
1886- int prepend_cmd , int fhin , int fhout , int fherr )
1948+ const char * dir , const char * prepend_cmd ,
1949+ int fhin , int fhout , int fherr )
18871950{
18881951 static int restrict_handle_inheritance = -1 ;
18891952 STARTUPINFOEXW si ;
@@ -1974,9 +2037,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19742037 /* concatenate argv, quoting args as we go */
19752038 strbuf_init (& args , 0 );
19762039 if (prepend_cmd ) {
1977- char * quoted = (char * )quote_arg (cmd );
2040+ char * quoted = (char * )quote_arg (prepend_cmd );
19782041 strbuf_addstr (& args , quoted );
1979- if (quoted != cmd )
2042+ if (quoted != prepend_cmd )
19802043 free (quoted );
19812044 }
19822045 for (; * argv ; argv ++ ) {
@@ -2135,7 +2198,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21352198 return (pid_t )pi .dwProcessId ;
21362199}
21372200
2138- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2201+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2202+ const char * prepend_cmd )
21392203{
21402204 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21412205}
@@ -2163,14 +2227,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21632227 pid = -1 ;
21642228 }
21652229 else {
2166- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2230+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21672231 fhin , fhout , fherr );
21682232 free (iprog );
21692233 }
21702234 argv [0 ] = argv0 ;
21712235 }
21722236 else
2173- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2237+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21742238 fhin , fhout , fherr );
21752239 free (prog );
21762240 }
@@ -2195,7 +2259,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21952259 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21962260 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21972261 exec_id = trace2_exec (prog , (const char * * )argv2 );
2198- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2262+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
21992263 if (pid >= 0 ) {
22002264 int status ;
22012265 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2219,7 +2283,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22192283 int exec_id ;
22202284
22212285 exec_id = trace2_exec (cmd , (const char * * )argv );
2222- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2286+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22232287 if (pid < 0 ) {
22242288 trace2_exec_result (exec_id , -1 );
22252289 return -1 ;
0 commit comments