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
@@ -1626,6 +1627,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16261627 return NULL ;
16271628}
16281629
1630+ static char * path_lookup (const char * cmd , int exe_only );
1631+
1632+ static char * is_busybox_applet (const char * cmd )
1633+ {
1634+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1635+ static char * busybox_path ;
1636+ static int busybox_path_initialized ;
1637+
1638+ /* Avoid infinite loop */
1639+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1640+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1641+ return NULL ;
1642+
1643+ if (!busybox_path_initialized ) {
1644+ busybox_path = path_lookup ("busybox.exe" , 1 );
1645+ busybox_path_initialized = 1 ;
1646+ }
1647+
1648+ /* Assume that sh is compiled in... */
1649+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1650+ return xstrdup_or_null (busybox_path );
1651+
1652+ if (!applets .nr ) {
1653+ struct child_process cp = CHILD_PROCESS_INIT ;
1654+ struct strbuf buf = STRBUF_INIT ;
1655+ char * p ;
1656+
1657+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1658+
1659+ if (capture_command (& cp , & buf , 2048 )) {
1660+ string_list_append (& applets , "" );
1661+ return NULL ;
1662+ }
1663+
1664+ /* parse output */
1665+ p = strstr (buf .buf , "Currently defined functions:\n" );
1666+ if (!p ) {
1667+ warning ("Could not parse output of busybox --help" );
1668+ string_list_append (& applets , "" );
1669+ return NULL ;
1670+ }
1671+ p = strchrnul (p , '\n' );
1672+ for (;;) {
1673+ size_t len ;
1674+
1675+ p += strspn (p , "\n\t ," );
1676+ len = strcspn (p , "\n\t ," );
1677+ if (!len )
1678+ break ;
1679+ p [len ] = '\0' ;
1680+ string_list_insert (& applets , p );
1681+ p = p + len + 1 ;
1682+ }
1683+ }
1684+
1685+ return string_list_has_string (& applets , cmd ) ?
1686+ xstrdup (busybox_path ) : NULL ;
1687+ }
1688+
16291689/*
16301690 * Determines the absolute path of cmd using the split path in path.
16311691 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1654,6 +1714,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16541714 path = sep + 1 ;
16551715 }
16561716
1717+ if (!prog && !isexe )
1718+ prog = is_busybox_applet (cmd );
1719+
16571720 return prog ;
16581721}
16591722
@@ -1853,8 +1916,8 @@ static int is_msys2_sh(const char *cmd)
18531916}
18541917
18551918static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1856- const char * dir ,
1857- int prepend_cmd , int fhin , int fhout , int fherr )
1919+ const char * dir , const char * prepend_cmd ,
1920+ int fhin , int fhout , int fherr )
18581921{
18591922 static int restrict_handle_inheritance = -1 ;
18601923 STARTUPINFOEXW si ;
@@ -1945,9 +2008,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19452008 /* concatenate argv, quoting args as we go */
19462009 strbuf_init (& args , 0 );
19472010 if (prepend_cmd ) {
1948- char * quoted = (char * )quote_arg (cmd );
2011+ char * quoted = (char * )quote_arg (prepend_cmd );
19492012 strbuf_addstr (& args , quoted );
1950- if (quoted != cmd )
2013+ if (quoted != prepend_cmd )
19512014 free (quoted );
19522015 }
19532016 for (; * argv ; argv ++ ) {
@@ -2106,7 +2169,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21062169 return (pid_t )pi .dwProcessId ;
21072170}
21082171
2109- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2172+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2173+ const char * prepend_cmd )
21102174{
21112175 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21122176}
@@ -2134,14 +2198,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21342198 pid = -1 ;
21352199 }
21362200 else {
2137- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2201+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21382202 fhin , fhout , fherr );
21392203 free (iprog );
21402204 }
21412205 argv [0 ] = argv0 ;
21422206 }
21432207 else
2144- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2208+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21452209 fhin , fhout , fherr );
21462210 free (prog );
21472211 }
@@ -2169,7 +2233,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21692233 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21702234 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21712235 exec_id = trace2_exec (prog , argv2 );
2172- pid = mingw_spawnv (prog , argv2 , 1 );
2236+ pid = mingw_spawnv (prog , argv2 , interpr );
21732237 if (pid >= 0 ) {
21742238 int status ;
21752239 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2193,7 +2257,7 @@ int mingw_execv(const char *cmd, char *const *argv)
21932257 int exec_id ;
21942258
21952259 exec_id = trace2_exec (cmd , (const char * * )argv );
2196- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2260+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
21972261 if (pid < 0 ) {
21982262 trace2_exec_result (exec_id , -1 );
21992263 return -1 ;
0 commit comments