2424#include "../repository.h"
2525#include "win32/fscache.h"
2626#include "../attr.h"
27+ #include "../string-list.h"
2728
2829#define HCAST (type , handle ) ((type)(intptr_t)handle)
2930
@@ -1665,6 +1666,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16651666 return NULL ;
16661667}
16671668
1669+ static char * path_lookup (const char * cmd , int exe_only );
1670+
1671+ static char * is_busybox_applet (const char * cmd )
1672+ {
1673+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1674+ static char * busybox_path ;
1675+ static int busybox_path_initialized ;
1676+
1677+ /* Avoid infinite loop */
1678+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1679+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1680+ return NULL ;
1681+
1682+ if (!busybox_path_initialized ) {
1683+ busybox_path = path_lookup ("busybox.exe" , 1 );
1684+ busybox_path_initialized = 1 ;
1685+ }
1686+
1687+ /* Assume that sh is compiled in... */
1688+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1689+ return xstrdup_or_null (busybox_path );
1690+
1691+ if (!applets .nr ) {
1692+ struct child_process cp = CHILD_PROCESS_INIT ;
1693+ struct strbuf buf = STRBUF_INIT ;
1694+ char * p ;
1695+
1696+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1697+
1698+ if (capture_command (& cp , & buf , 2048 )) {
1699+ string_list_append (& applets , "" );
1700+ return NULL ;
1701+ }
1702+
1703+ /* parse output */
1704+ p = strstr (buf .buf , "Currently defined functions:\n" );
1705+ if (!p ) {
1706+ warning ("Could not parse output of busybox --help" );
1707+ string_list_append (& applets , "" );
1708+ return NULL ;
1709+ }
1710+ p = strchrnul (p , '\n' );
1711+ for (;;) {
1712+ size_t len ;
1713+
1714+ p += strspn (p , "\n\t ," );
1715+ len = strcspn (p , "\n\t ," );
1716+ if (!len )
1717+ break ;
1718+ p [len ] = '\0' ;
1719+ string_list_insert (& applets , p );
1720+ p = p + len + 1 ;
1721+ }
1722+ }
1723+
1724+ return string_list_has_string (& applets , cmd ) ?
1725+ xstrdup (busybox_path ) : NULL ;
1726+ }
1727+
16681728/*
16691729 * Determines the absolute path of cmd using the split path in path.
16701730 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1693,6 +1753,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16931753 path = sep + 1 ;
16941754 }
16951755
1756+ if (!prog && !isexe )
1757+ prog = is_busybox_applet (cmd );
1758+
16961759 return prog ;
16971760}
16981761
@@ -1896,8 +1959,8 @@ static int is_msys2_sh(const char *cmd)
18961959}
18971960
18981961static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1899- const char * dir ,
1900- int prepend_cmd , int fhin , int fhout , int fherr )
1962+ const char * dir , const char * prepend_cmd ,
1963+ int fhin , int fhout , int fherr )
19011964{
19021965 static int restrict_handle_inheritance = -1 ;
19031966 STARTUPINFOEXW si ;
@@ -1988,9 +2051,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19882051 /* concatenate argv, quoting args as we go */
19892052 strbuf_init (& args , 0 );
19902053 if (prepend_cmd ) {
1991- char * quoted = (char * )quote_arg (cmd );
2054+ char * quoted = (char * )quote_arg (prepend_cmd );
19922055 strbuf_addstr (& args , quoted );
1993- if (quoted != cmd )
2056+ if (quoted != prepend_cmd )
19942057 free (quoted );
19952058 }
19962059 for (; * argv ; argv ++ ) {
@@ -2149,7 +2212,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21492212 return (pid_t )pi .dwProcessId ;
21502213}
21512214
2152- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2215+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2216+ const char * prepend_cmd )
21532217{
21542218 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21552219}
@@ -2177,14 +2241,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21772241 pid = -1 ;
21782242 }
21792243 else {
2180- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2244+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21812245 fhin , fhout , fherr );
21822246 free (iprog );
21832247 }
21842248 argv [0 ] = argv0 ;
21852249 }
21862250 else
2187- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2251+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21882252 fhin , fhout , fherr );
21892253 free (prog );
21902254 }
@@ -2209,7 +2273,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22092273 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22102274 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22112275 exec_id = trace2_exec (prog , (const char * * )argv2 );
2212- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2276+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22132277 if (pid >= 0 ) {
22142278 int status ;
22152279 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2233,7 +2297,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22332297 int exec_id ;
22342298
22352299 exec_id = trace2_exec (cmd , (const char * * )argv );
2236- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2300+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22372301 if (pid < 0 ) {
22382302 trace2_exec_result (exec_id , -1 );
22392303 return -1 ;
0 commit comments