2626#include "../repository.h"
2727#include "win32/fscache.h"
2828#include "../attr.h"
29+ #include "../string-list.h"
2930
3031#define HCAST (type , handle ) ((type)(intptr_t)handle)
3132
@@ -1735,6 +1736,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
17351736 return NULL ;
17361737}
17371738
1739+ static char * path_lookup (const char * cmd , int exe_only );
1740+
1741+ static char * is_busybox_applet (const char * cmd )
1742+ {
1743+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1744+ static char * busybox_path ;
1745+ static int busybox_path_initialized ;
1746+
1747+ /* Avoid infinite loop */
1748+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1749+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1750+ return NULL ;
1751+
1752+ if (!busybox_path_initialized ) {
1753+ busybox_path = path_lookup ("busybox.exe" , 1 );
1754+ busybox_path_initialized = 1 ;
1755+ }
1756+
1757+ /* Assume that sh is compiled in... */
1758+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1759+ return xstrdup_or_null (busybox_path );
1760+
1761+ if (!applets .nr ) {
1762+ struct child_process cp = CHILD_PROCESS_INIT ;
1763+ struct strbuf buf = STRBUF_INIT ;
1764+ char * p ;
1765+
1766+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1767+
1768+ if (capture_command (& cp , & buf , 2048 )) {
1769+ string_list_append (& applets , "" );
1770+ return NULL ;
1771+ }
1772+
1773+ /* parse output */
1774+ p = strstr (buf .buf , "Currently defined functions:\n" );
1775+ if (!p ) {
1776+ warning ("Could not parse output of busybox --help" );
1777+ string_list_append (& applets , "" );
1778+ return NULL ;
1779+ }
1780+ p = strchrnul (p , '\n' );
1781+ for (;;) {
1782+ size_t len ;
1783+
1784+ p += strspn (p , "\n\t ," );
1785+ len = strcspn (p , "\n\t ," );
1786+ if (!len )
1787+ break ;
1788+ p [len ] = '\0' ;
1789+ string_list_insert (& applets , p );
1790+ p = p + len + 1 ;
1791+ }
1792+ }
1793+
1794+ return string_list_has_string (& applets , cmd ) ?
1795+ xstrdup (busybox_path ) : NULL ;
1796+ }
1797+
17381798/*
17391799 * Determines the absolute path of cmd using the split path in path.
17401800 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1763,6 +1823,9 @@ static char *path_lookup(const char *cmd, int exe_only)
17631823 path = sep + 1 ;
17641824 }
17651825
1826+ if (!prog && !isexe )
1827+ prog = is_busybox_applet (cmd );
1828+
17661829 return prog ;
17671830}
17681831
@@ -1966,8 +2029,8 @@ static int is_msys2_sh(const char *cmd)
19662029}
19672030
19682031static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1969- const char * dir ,
1970- int prepend_cmd , int fhin , int fhout , int fherr )
2032+ const char * dir , const char * prepend_cmd ,
2033+ int fhin , int fhout , int fherr )
19712034{
19722035 static int restrict_handle_inheritance = -1 ;
19732036 STARTUPINFOEXW si ;
@@ -2058,9 +2121,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20582121 /* concatenate argv, quoting args as we go */
20592122 strbuf_init (& args , 0 );
20602123 if (prepend_cmd ) {
2061- char * quoted = (char * )quote_arg (cmd );
2124+ char * quoted = (char * )quote_arg (prepend_cmd );
20622125 strbuf_addstr (& args , quoted );
2063- if (quoted != cmd )
2126+ if (quoted != prepend_cmd )
20642127 free (quoted );
20652128 }
20662129 for (; * argv ; argv ++ ) {
@@ -2219,7 +2282,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
22192282 return (pid_t )pi .dwProcessId ;
22202283}
22212284
2222- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2285+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2286+ const char * prepend_cmd )
22232287{
22242288 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
22252289}
@@ -2247,14 +2311,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
22472311 pid = -1 ;
22482312 }
22492313 else {
2250- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2314+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
22512315 fhin , fhout , fherr );
22522316 free (iprog );
22532317 }
22542318 argv [0 ] = argv0 ;
22552319 }
22562320 else
2257- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2321+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
22582322 fhin , fhout , fherr );
22592323 free (prog );
22602324 }
@@ -2279,7 +2343,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22792343 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22802344 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22812345 exec_id = trace2_exec (prog , (const char * * )argv2 );
2282- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2346+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22832347 if (pid >= 0 ) {
22842348 int status ;
22852349 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2303,7 +2367,7 @@ int mingw_execv(const char *cmd, char *const *argv)
23032367 int exec_id ;
23042368
23052369 exec_id = trace2_exec (cmd , (const char * * )argv );
2306- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2370+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
23072371 if (pid < 0 ) {
23082372 trace2_exec_result (exec_id , -1 );
23092373 return -1 ;
0 commit comments