1414#include <sspi.h>
1515#include "win32/fscache.h"
1616#include "../attr.h"
17+ #include "../string-list.h"
1718
1819#define HCAST (type , handle ) ((type)(intptr_t)handle)
1920
@@ -1585,6 +1586,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
15851586 return NULL ;
15861587}
15871588
1589+ static char * path_lookup (const char * cmd , int exe_only );
1590+
1591+ static char * is_busybox_applet (const char * cmd )
1592+ {
1593+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1594+ static char * busybox_path ;
1595+ static int busybox_path_initialized ;
1596+
1597+ /* Avoid infinite loop */
1598+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1599+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1600+ return NULL ;
1601+
1602+ if (!busybox_path_initialized ) {
1603+ busybox_path = path_lookup ("busybox.exe" , 1 );
1604+ busybox_path_initialized = 1 ;
1605+ }
1606+
1607+ /* Assume that sh is compiled in... */
1608+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1609+ return xstrdup_or_null (busybox_path );
1610+
1611+ if (!applets .nr ) {
1612+ struct child_process cp = CHILD_PROCESS_INIT ;
1613+ struct strbuf buf = STRBUF_INIT ;
1614+ char * p ;
1615+
1616+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1617+
1618+ if (capture_command (& cp , & buf , 2048 )) {
1619+ string_list_append (& applets , "" );
1620+ return NULL ;
1621+ }
1622+
1623+ /* parse output */
1624+ p = strstr (buf .buf , "Currently defined functions:\n" );
1625+ if (!p ) {
1626+ warning ("Could not parse output of busybox --help" );
1627+ string_list_append (& applets , "" );
1628+ return NULL ;
1629+ }
1630+ p = strchrnul (p , '\n' );
1631+ for (;;) {
1632+ size_t len ;
1633+
1634+ p += strspn (p , "\n\t ," );
1635+ len = strcspn (p , "\n\t ," );
1636+ if (!len )
1637+ break ;
1638+ p [len ] = '\0' ;
1639+ string_list_insert (& applets , p );
1640+ p = p + len + 1 ;
1641+ }
1642+ }
1643+
1644+ return string_list_has_string (& applets , cmd ) ?
1645+ xstrdup (busybox_path ) : NULL ;
1646+ }
1647+
15881648/*
15891649 * Determines the absolute path of cmd using the split path in path.
15901650 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1613,6 +1673,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16131673 path = sep + 1 ;
16141674 }
16151675
1676+ if (!prog && !isexe )
1677+ prog = is_busybox_applet (cmd );
1678+
16161679 return prog ;
16171680}
16181681
@@ -1812,8 +1875,8 @@ static int is_msys2_sh(const char *cmd)
18121875}
18131876
18141877static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1815- const char * dir ,
1816- int prepend_cmd , int fhin , int fhout , int fherr )
1878+ const char * dir , const char * prepend_cmd ,
1879+ int fhin , int fhout , int fherr )
18171880{
18181881 static int restrict_handle_inheritance = -1 ;
18191882 STARTUPINFOEXW si ;
@@ -1904,9 +1967,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19041967 /* concatenate argv, quoting args as we go */
19051968 strbuf_init (& args , 0 );
19061969 if (prepend_cmd ) {
1907- char * quoted = (char * )quote_arg (cmd );
1970+ char * quoted = (char * )quote_arg (prepend_cmd );
19081971 strbuf_addstr (& args , quoted );
1909- if (quoted != cmd )
1972+ if (quoted != prepend_cmd )
19101973 free (quoted );
19111974 }
19121975 for (; * argv ; argv ++ ) {
@@ -2065,7 +2128,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20652128 return (pid_t )pi .dwProcessId ;
20662129}
20672130
2068- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2131+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2132+ const char * prepend_cmd )
20692133{
20702134 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
20712135}
@@ -2093,14 +2157,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
20932157 pid = -1 ;
20942158 }
20952159 else {
2096- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2160+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
20972161 fhin , fhout , fherr );
20982162 free (iprog );
20992163 }
21002164 argv [0 ] = argv0 ;
21012165 }
21022166 else
2103- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2167+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21042168 fhin , fhout , fherr );
21052169 free (prog );
21062170 }
@@ -2128,7 +2192,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21282192 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21292193 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21302194 exec_id = trace2_exec (prog , argv2 );
2131- pid = mingw_spawnv (prog , argv2 , 1 );
2195+ pid = mingw_spawnv (prog , argv2 , interpr );
21322196 if (pid >= 0 ) {
21332197 int status ;
21342198 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2152,7 +2216,7 @@ int mingw_execv(const char *cmd, char *const *argv)
21522216 int exec_id ;
21532217
21542218 exec_id = trace2_exec (cmd , (const char * * )argv );
2155- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2219+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
21562220 if (pid < 0 ) {
21572221 trace2_exec_result (exec_id , -1 );
21582222 return -1 ;
0 commit comments