2525#include "../repository.h"
2626#include "win32/fscache.h"
2727#include "../attr.h"
28+ #include "../string-list.h"
2829
2930#define HCAST (type , handle ) ((type)(intptr_t)handle)
3031
@@ -1667,6 +1668,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16671668 return NULL ;
16681669}
16691670
1671+ static char * path_lookup (const char * cmd , int exe_only );
1672+
1673+ static char * is_busybox_applet (const char * cmd )
1674+ {
1675+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1676+ static char * busybox_path ;
1677+ static int busybox_path_initialized ;
1678+
1679+ /* Avoid infinite loop */
1680+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1681+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1682+ return NULL ;
1683+
1684+ if (!busybox_path_initialized ) {
1685+ busybox_path = path_lookup ("busybox.exe" , 1 );
1686+ busybox_path_initialized = 1 ;
1687+ }
1688+
1689+ /* Assume that sh is compiled in... */
1690+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1691+ return xstrdup_or_null (busybox_path );
1692+
1693+ if (!applets .nr ) {
1694+ struct child_process cp = CHILD_PROCESS_INIT ;
1695+ struct strbuf buf = STRBUF_INIT ;
1696+ char * p ;
1697+
1698+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1699+
1700+ if (capture_command (& cp , & buf , 2048 )) {
1701+ string_list_append (& applets , "" );
1702+ return NULL ;
1703+ }
1704+
1705+ /* parse output */
1706+ p = strstr (buf .buf , "Currently defined functions:\n" );
1707+ if (!p ) {
1708+ warning ("Could not parse output of busybox --help" );
1709+ string_list_append (& applets , "" );
1710+ return NULL ;
1711+ }
1712+ p = strchrnul (p , '\n' );
1713+ for (;;) {
1714+ size_t len ;
1715+
1716+ p += strspn (p , "\n\t ," );
1717+ len = strcspn (p , "\n\t ," );
1718+ if (!len )
1719+ break ;
1720+ p [len ] = '\0' ;
1721+ string_list_insert (& applets , p );
1722+ p = p + len + 1 ;
1723+ }
1724+ }
1725+
1726+ return string_list_has_string (& applets , cmd ) ?
1727+ xstrdup (busybox_path ) : NULL ;
1728+ }
1729+
16701730/*
16711731 * Determines the absolute path of cmd using the split path in path.
16721732 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1695,6 +1755,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16951755 path = sep + 1 ;
16961756 }
16971757
1758+ if (!prog && !isexe )
1759+ prog = is_busybox_applet (cmd );
1760+
16981761 return prog ;
16991762}
17001763
@@ -1898,8 +1961,8 @@ static int is_msys2_sh(const char *cmd)
18981961}
18991962
19001963static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1901- const char * dir ,
1902- int prepend_cmd , int fhin , int fhout , int fherr )
1964+ const char * dir , const char * prepend_cmd ,
1965+ int fhin , int fhout , int fherr )
19031966{
19041967 static int restrict_handle_inheritance = -1 ;
19051968 STARTUPINFOEXW si ;
@@ -1990,9 +2053,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19902053 /* concatenate argv, quoting args as we go */
19912054 strbuf_init (& args , 0 );
19922055 if (prepend_cmd ) {
1993- char * quoted = (char * )quote_arg (cmd );
2056+ char * quoted = (char * )quote_arg (prepend_cmd );
19942057 strbuf_addstr (& args , quoted );
1995- if (quoted != cmd )
2058+ if (quoted != prepend_cmd )
19962059 free (quoted );
19972060 }
19982061 for (; * argv ; argv ++ ) {
@@ -2151,7 +2214,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21512214 return (pid_t )pi .dwProcessId ;
21522215}
21532216
2154- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2217+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2218+ const char * prepend_cmd )
21552219{
21562220 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21572221}
@@ -2179,14 +2243,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21792243 pid = -1 ;
21802244 }
21812245 else {
2182- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2246+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21832247 fhin , fhout , fherr );
21842248 free (iprog );
21852249 }
21862250 argv [0 ] = argv0 ;
21872251 }
21882252 else
2189- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2253+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21902254 fhin , fhout , fherr );
21912255 free (prog );
21922256 }
@@ -2211,7 +2275,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22112275 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22122276 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22132277 exec_id = trace2_exec (prog , (const char * * )argv2 );
2214- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2278+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22152279 if (pid >= 0 ) {
22162280 int status ;
22172281 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2235,7 +2299,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22352299 int exec_id ;
22362300
22372301 exec_id = trace2_exec (cmd , (const char * * )argv );
2238- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2302+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22392303 if (pid < 0 ) {
22402304 trace2_exec_result (exec_id , -1 );
22412305 return -1 ;
0 commit comments