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
@@ -1642,6 +1643,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16421643 return NULL ;
16431644}
16441645
1646+ static char * path_lookup (const char * cmd , int exe_only );
1647+
1648+ static char * is_busybox_applet (const char * cmd )
1649+ {
1650+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1651+ static char * busybox_path ;
1652+ static int busybox_path_initialized ;
1653+
1654+ /* Avoid infinite loop */
1655+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1656+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1657+ return NULL ;
1658+
1659+ if (!busybox_path_initialized ) {
1660+ busybox_path = path_lookup ("busybox.exe" , 1 );
1661+ busybox_path_initialized = 1 ;
1662+ }
1663+
1664+ /* Assume that sh is compiled in... */
1665+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1666+ return xstrdup_or_null (busybox_path );
1667+
1668+ if (!applets .nr ) {
1669+ struct child_process cp = CHILD_PROCESS_INIT ;
1670+ struct strbuf buf = STRBUF_INIT ;
1671+ char * p ;
1672+
1673+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1674+
1675+ if (capture_command (& cp , & buf , 2048 )) {
1676+ string_list_append (& applets , "" );
1677+ return NULL ;
1678+ }
1679+
1680+ /* parse output */
1681+ p = strstr (buf .buf , "Currently defined functions:\n" );
1682+ if (!p ) {
1683+ warning ("Could not parse output of busybox --help" );
1684+ string_list_append (& applets , "" );
1685+ return NULL ;
1686+ }
1687+ p = strchrnul (p , '\n' );
1688+ for (;;) {
1689+ size_t len ;
1690+
1691+ p += strspn (p , "\n\t ," );
1692+ len = strcspn (p , "\n\t ," );
1693+ if (!len )
1694+ break ;
1695+ p [len ] = '\0' ;
1696+ string_list_insert (& applets , p );
1697+ p = p + len + 1 ;
1698+ }
1699+ }
1700+
1701+ return string_list_has_string (& applets , cmd ) ?
1702+ xstrdup (busybox_path ) : NULL ;
1703+ }
1704+
16451705/*
16461706 * Determines the absolute path of cmd using the split path in path.
16471707 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1670,6 +1730,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16701730 path = sep + 1 ;
16711731 }
16721732
1733+ if (!prog && !isexe )
1734+ prog = is_busybox_applet (cmd );
1735+
16731736 return prog ;
16741737}
16751738
@@ -1868,8 +1931,8 @@ static int is_msys2_sh(const char *cmd)
18681931}
18691932
18701933static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1871- const char * dir ,
1872- int prepend_cmd , int fhin , int fhout , int fherr )
1934+ const char * dir , const char * prepend_cmd ,
1935+ int fhin , int fhout , int fherr )
18731936{
18741937 static int restrict_handle_inheritance = -1 ;
18751938 STARTUPINFOEXW si ;
@@ -1960,9 +2023,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19602023 /* concatenate argv, quoting args as we go */
19612024 strbuf_init (& args , 0 );
19622025 if (prepend_cmd ) {
1963- char * quoted = (char * )quote_arg (cmd );
2026+ char * quoted = (char * )quote_arg (prepend_cmd );
19642027 strbuf_addstr (& args , quoted );
1965- if (quoted != cmd )
2028+ if (quoted != prepend_cmd )
19662029 free (quoted );
19672030 }
19682031 for (; * argv ; argv ++ ) {
@@ -2121,7 +2184,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21212184 return (pid_t )pi .dwProcessId ;
21222185}
21232186
2124- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2187+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2188+ const char * prepend_cmd )
21252189{
21262190 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21272191}
@@ -2149,14 +2213,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21492213 pid = -1 ;
21502214 }
21512215 else {
2152- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2216+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21532217 fhin , fhout , fherr );
21542218 free (iprog );
21552219 }
21562220 argv [0 ] = argv0 ;
21572221 }
21582222 else
2159- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2223+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21602224 fhin , fhout , fherr );
21612225 free (prog );
21622226 }
@@ -2181,7 +2245,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21812245 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21822246 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21832247 exec_id = trace2_exec (prog , (const char * * )argv2 );
2184- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2248+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
21852249 if (pid >= 0 ) {
21862250 int status ;
21872251 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2205,7 +2269,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22052269 int exec_id ;
22062270
22072271 exec_id = trace2_exec (cmd , (const char * * )argv );
2208- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2272+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22092273 if (pid < 0 ) {
22102274 trace2_exec_result (exec_id , -1 );
22112275 return -1 ;
0 commit comments