1313#include <sspi.h>
1414#include "win32/fscache.h"
1515#include "../attr.h"
16+ #include "../string-list.h"
1617
1718#define HCAST (type , handle ) ((type)(intptr_t)handle)
1819
@@ -1584,6 +1585,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
15841585 return NULL ;
15851586}
15861587
1588+ static char * path_lookup (const char * cmd , int exe_only );
1589+
1590+ static char * is_busybox_applet (const char * cmd )
1591+ {
1592+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1593+ static char * busybox_path ;
1594+ static int busybox_path_initialized ;
1595+
1596+ /* Avoid infinite loop */
1597+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1598+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1599+ return NULL ;
1600+
1601+ if (!busybox_path_initialized ) {
1602+ busybox_path = path_lookup ("busybox.exe" , 1 );
1603+ busybox_path_initialized = 1 ;
1604+ }
1605+
1606+ /* Assume that sh is compiled in... */
1607+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1608+ return xstrdup_or_null (busybox_path );
1609+
1610+ if (!applets .nr ) {
1611+ struct child_process cp = CHILD_PROCESS_INIT ;
1612+ struct strbuf buf = STRBUF_INIT ;
1613+ char * p ;
1614+
1615+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1616+
1617+ if (capture_command (& cp , & buf , 2048 )) {
1618+ string_list_append (& applets , "" );
1619+ return NULL ;
1620+ }
1621+
1622+ /* parse output */
1623+ p = strstr (buf .buf , "Currently defined functions:\n" );
1624+ if (!p ) {
1625+ warning ("Could not parse output of busybox --help" );
1626+ string_list_append (& applets , "" );
1627+ return NULL ;
1628+ }
1629+ p = strchrnul (p , '\n' );
1630+ for (;;) {
1631+ size_t len ;
1632+
1633+ p += strspn (p , "\n\t ," );
1634+ len = strcspn (p , "\n\t ," );
1635+ if (!len )
1636+ break ;
1637+ p [len ] = '\0' ;
1638+ string_list_insert (& applets , p );
1639+ p = p + len + 1 ;
1640+ }
1641+ }
1642+
1643+ return string_list_has_string (& applets , cmd ) ?
1644+ xstrdup (busybox_path ) : NULL ;
1645+ }
1646+
15871647/*
15881648 * Determines the absolute path of cmd using the split path in path.
15891649 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1612,6 +1672,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16121672 path = sep + 1 ;
16131673 }
16141674
1675+ if (!prog && !isexe )
1676+ prog = is_busybox_applet (cmd );
1677+
16151678 return prog ;
16161679}
16171680
@@ -1811,8 +1874,8 @@ static int is_msys2_sh(const char *cmd)
18111874}
18121875
18131876static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1814- const char * dir ,
1815- int prepend_cmd , int fhin , int fhout , int fherr )
1877+ const char * dir , const char * prepend_cmd ,
1878+ int fhin , int fhout , int fherr )
18161879{
18171880 static int restrict_handle_inheritance = -1 ;
18181881 STARTUPINFOEXW si ;
@@ -1903,9 +1966,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19031966 /* concatenate argv, quoting args as we go */
19041967 strbuf_init (& args , 0 );
19051968 if (prepend_cmd ) {
1906- char * quoted = (char * )quote_arg (cmd );
1969+ char * quoted = (char * )quote_arg (prepend_cmd );
19071970 strbuf_addstr (& args , quoted );
1908- if (quoted != cmd )
1971+ if (quoted != prepend_cmd )
19091972 free (quoted );
19101973 }
19111974 for (; * argv ; argv ++ ) {
@@ -2064,7 +2127,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20642127 return (pid_t )pi .dwProcessId ;
20652128}
20662129
2067- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2130+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2131+ const char * prepend_cmd )
20682132{
20692133 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
20702134}
@@ -2092,14 +2156,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
20922156 pid = -1 ;
20932157 }
20942158 else {
2095- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2159+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
20962160 fhin , fhout , fherr );
20972161 free (iprog );
20982162 }
20992163 argv [0 ] = argv0 ;
21002164 }
21012165 else
2102- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2166+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21032167 fhin , fhout , fherr );
21042168 free (prog );
21052169 }
@@ -2127,7 +2191,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21272191 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21282192 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21292193 exec_id = trace2_exec (prog , argv2 );
2130- pid = mingw_spawnv (prog , argv2 , 1 );
2194+ pid = mingw_spawnv (prog , argv2 , interpr );
21312195 if (pid >= 0 ) {
21322196 int status ;
21332197 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2151,7 +2215,7 @@ int mingw_execv(const char *cmd, char *const *argv)
21512215 int exec_id ;
21522216
21532217 exec_id = trace2_exec (cmd , (const char * * )argv );
2154- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2218+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
21552219 if (pid < 0 ) {
21562220 trace2_exec_result (exec_id , -1 );
21572221 return -1 ;
0 commit comments