1515#include <sspi.h>
1616#include "win32/fscache.h"
1717#include "../attr.h"
18+ #include "../string-list.h"
1819
1920#define HCAST (type , handle ) ((type)(intptr_t)handle)
2021
@@ -1586,6 +1587,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
15861587 return NULL ;
15871588}
15881589
1590+ static char * path_lookup (const char * cmd , int exe_only );
1591+
1592+ static char * is_busybox_applet (const char * cmd )
1593+ {
1594+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1595+ static char * busybox_path ;
1596+ static int busybox_path_initialized ;
1597+
1598+ /* Avoid infinite loop */
1599+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1600+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1601+ return NULL ;
1602+
1603+ if (!busybox_path_initialized ) {
1604+ busybox_path = path_lookup ("busybox.exe" , 1 );
1605+ busybox_path_initialized = 1 ;
1606+ }
1607+
1608+ /* Assume that sh is compiled in... */
1609+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1610+ return xstrdup_or_null (busybox_path );
1611+
1612+ if (!applets .nr ) {
1613+ struct child_process cp = CHILD_PROCESS_INIT ;
1614+ struct strbuf buf = STRBUF_INIT ;
1615+ char * p ;
1616+
1617+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1618+
1619+ if (capture_command (& cp , & buf , 2048 )) {
1620+ string_list_append (& applets , "" );
1621+ return NULL ;
1622+ }
1623+
1624+ /* parse output */
1625+ p = strstr (buf .buf , "Currently defined functions:\n" );
1626+ if (!p ) {
1627+ warning ("Could not parse output of busybox --help" );
1628+ string_list_append (& applets , "" );
1629+ return NULL ;
1630+ }
1631+ p = strchrnul (p , '\n' );
1632+ for (;;) {
1633+ size_t len ;
1634+
1635+ p += strspn (p , "\n\t ," );
1636+ len = strcspn (p , "\n\t ," );
1637+ if (!len )
1638+ break ;
1639+ p [len ] = '\0' ;
1640+ string_list_insert (& applets , p );
1641+ p = p + len + 1 ;
1642+ }
1643+ }
1644+
1645+ return string_list_has_string (& applets , cmd ) ?
1646+ xstrdup (busybox_path ) : NULL ;
1647+ }
1648+
15891649/*
15901650 * Determines the absolute path of cmd using the split path in path.
15911651 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1614,6 +1674,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16141674 path = sep + 1 ;
16151675 }
16161676
1677+ if (!prog && !isexe )
1678+ prog = is_busybox_applet (cmd );
1679+
16171680 return prog ;
16181681}
16191682
@@ -1813,8 +1876,8 @@ static int is_msys2_sh(const char *cmd)
18131876}
18141877
18151878static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1816- const char * dir ,
1817- int prepend_cmd , int fhin , int fhout , int fherr )
1879+ const char * dir , const char * prepend_cmd ,
1880+ int fhin , int fhout , int fherr )
18181881{
18191882 static int restrict_handle_inheritance = -1 ;
18201883 STARTUPINFOEXW si ;
@@ -1905,9 +1968,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19051968 /* concatenate argv, quoting args as we go */
19061969 strbuf_init (& args , 0 );
19071970 if (prepend_cmd ) {
1908- char * quoted = (char * )quote_arg (cmd );
1971+ char * quoted = (char * )quote_arg (prepend_cmd );
19091972 strbuf_addstr (& args , quoted );
1910- if (quoted != cmd )
1973+ if (quoted != prepend_cmd )
19111974 free (quoted );
19121975 }
19131976 for (; * argv ; argv ++ ) {
@@ -2066,7 +2129,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20662129 return (pid_t )pi .dwProcessId ;
20672130}
20682131
2069- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2132+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2133+ const char * prepend_cmd )
20702134{
20712135 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
20722136}
@@ -2094,14 +2158,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
20942158 pid = -1 ;
20952159 }
20962160 else {
2097- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2161+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
20982162 fhin , fhout , fherr );
20992163 free (iprog );
21002164 }
21012165 argv [0 ] = argv0 ;
21022166 }
21032167 else
2104- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2168+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21052169 fhin , fhout , fherr );
21062170 free (prog );
21072171 }
@@ -2129,7 +2193,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21292193 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21302194 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21312195 exec_id = trace2_exec (prog , argv2 );
2132- pid = mingw_spawnv (prog , argv2 , 1 );
2196+ pid = mingw_spawnv (prog , argv2 , interpr );
21332197 if (pid >= 0 ) {
21342198 int status ;
21352199 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2153,7 +2217,7 @@ int mingw_execv(const char *cmd, char *const *argv)
21532217 int exec_id ;
21542218
21552219 exec_id = trace2_exec (cmd , (const char * * )argv );
2156- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2220+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
21572221 if (pid < 0 ) {
21582222 trace2_exec_result (exec_id , -1 );
21592223 return -1 ;
0 commit comments