2222#include <sspi.h>
2323#include "win32/fscache.h"
2424#include "../attr.h"
25+ #include "../string-list.h"
2526
2627#define HCAST (type , handle ) ((type)(intptr_t)handle)
2728
@@ -1649,6 +1650,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16491650 return NULL ;
16501651}
16511652
1653+ static char * path_lookup (const char * cmd , int exe_only );
1654+
1655+ static char * is_busybox_applet (const char * cmd )
1656+ {
1657+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1658+ static char * busybox_path ;
1659+ static int busybox_path_initialized ;
1660+
1661+ /* Avoid infinite loop */
1662+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1663+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1664+ return NULL ;
1665+
1666+ if (!busybox_path_initialized ) {
1667+ busybox_path = path_lookup ("busybox.exe" , 1 );
1668+ busybox_path_initialized = 1 ;
1669+ }
1670+
1671+ /* Assume that sh is compiled in... */
1672+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1673+ return xstrdup_or_null (busybox_path );
1674+
1675+ if (!applets .nr ) {
1676+ struct child_process cp = CHILD_PROCESS_INIT ;
1677+ struct strbuf buf = STRBUF_INIT ;
1678+ char * p ;
1679+
1680+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1681+
1682+ if (capture_command (& cp , & buf , 2048 )) {
1683+ string_list_append (& applets , "" );
1684+ return NULL ;
1685+ }
1686+
1687+ /* parse output */
1688+ p = strstr (buf .buf , "Currently defined functions:\n" );
1689+ if (!p ) {
1690+ warning ("Could not parse output of busybox --help" );
1691+ string_list_append (& applets , "" );
1692+ return NULL ;
1693+ }
1694+ p = strchrnul (p , '\n' );
1695+ for (;;) {
1696+ size_t len ;
1697+
1698+ p += strspn (p , "\n\t ," );
1699+ len = strcspn (p , "\n\t ," );
1700+ if (!len )
1701+ break ;
1702+ p [len ] = '\0' ;
1703+ string_list_insert (& applets , p );
1704+ p = p + len + 1 ;
1705+ }
1706+ }
1707+
1708+ return string_list_has_string (& applets , cmd ) ?
1709+ xstrdup (busybox_path ) : NULL ;
1710+ }
1711+
16521712/*
16531713 * Determines the absolute path of cmd using the split path in path.
16541714 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1677,6 +1737,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16771737 path = sep + 1 ;
16781738 }
16791739
1740+ if (!prog && !isexe )
1741+ prog = is_busybox_applet (cmd );
1742+
16801743 return prog ;
16811744}
16821745
@@ -1875,8 +1938,8 @@ static int is_msys2_sh(const char *cmd)
18751938}
18761939
18771940static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1878- const char * dir ,
1879- int prepend_cmd , int fhin , int fhout , int fherr )
1941+ const char * dir , const char * prepend_cmd ,
1942+ int fhin , int fhout , int fherr )
18801943{
18811944 static int restrict_handle_inheritance = -1 ;
18821945 STARTUPINFOEXW si ;
@@ -1967,9 +2030,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19672030 /* concatenate argv, quoting args as we go */
19682031 strbuf_init (& args , 0 );
19692032 if (prepend_cmd ) {
1970- char * quoted = (char * )quote_arg (cmd );
2033+ char * quoted = (char * )quote_arg (prepend_cmd );
19712034 strbuf_addstr (& args , quoted );
1972- if (quoted != cmd )
2035+ if (quoted != prepend_cmd )
19732036 free (quoted );
19742037 }
19752038 for (; * argv ; argv ++ ) {
@@ -2128,7 +2191,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21282191 return (pid_t )pi .dwProcessId ;
21292192}
21302193
2131- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2194+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2195+ const char * prepend_cmd )
21322196{
21332197 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21342198}
@@ -2156,14 +2220,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21562220 pid = -1 ;
21572221 }
21582222 else {
2159- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2223+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21602224 fhin , fhout , fherr );
21612225 free (iprog );
21622226 }
21632227 argv [0 ] = argv0 ;
21642228 }
21652229 else
2166- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2230+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21672231 fhin , fhout , fherr );
21682232 free (prog );
21692233 }
@@ -2188,7 +2252,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21882252 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21892253 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21902254 exec_id = trace2_exec (prog , (const char * * )argv2 );
2191- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2255+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
21922256 if (pid >= 0 ) {
21932257 int status ;
21942258 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2212,7 +2276,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22122276 int exec_id ;
22132277
22142278 exec_id = trace2_exec (cmd , (const char * * )argv );
2215- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2279+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22162280 if (pid < 0 ) {
22172281 trace2_exec_result (exec_id , -1 );
22182282 return -1 ;
0 commit comments