2222#include "../repository.h"
2323#include "win32/fscache.h"
2424#include "../attr.h"
25+ #include "../string-list.h"
2526#include "dir.h"
2627#include "gettext.h"
2728#define SECURITY_WIN32
@@ -1759,6 +1760,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
17591760 return NULL ;
17601761}
17611762
1763+ static char * path_lookup (const char * cmd , int exe_only );
1764+
1765+ static char * is_busybox_applet (const char * cmd )
1766+ {
1767+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1768+ static char * busybox_path ;
1769+ static int busybox_path_initialized ;
1770+
1771+ /* Avoid infinite loop */
1772+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1773+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1774+ return NULL ;
1775+
1776+ if (!busybox_path_initialized ) {
1777+ busybox_path = path_lookup ("busybox.exe" , 1 );
1778+ busybox_path_initialized = 1 ;
1779+ }
1780+
1781+ /* Assume that sh is compiled in... */
1782+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1783+ return xstrdup_or_null (busybox_path );
1784+
1785+ if (!applets .nr ) {
1786+ struct child_process cp = CHILD_PROCESS_INIT ;
1787+ struct strbuf buf = STRBUF_INIT ;
1788+ char * p ;
1789+
1790+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1791+
1792+ if (capture_command (& cp , & buf , 2048 )) {
1793+ string_list_append (& applets , "" );
1794+ return NULL ;
1795+ }
1796+
1797+ /* parse output */
1798+ p = strstr (buf .buf , "Currently defined functions:\n" );
1799+ if (!p ) {
1800+ warning ("Could not parse output of busybox --help" );
1801+ string_list_append (& applets , "" );
1802+ return NULL ;
1803+ }
1804+ p = strchrnul (p , '\n' );
1805+ for (;;) {
1806+ size_t len ;
1807+
1808+ p += strspn (p , "\n\t ," );
1809+ len = strcspn (p , "\n\t ," );
1810+ if (!len )
1811+ break ;
1812+ p [len ] = '\0' ;
1813+ string_list_insert (& applets , p );
1814+ p = p + len + 1 ;
1815+ }
1816+ }
1817+
1818+ return string_list_has_string (& applets , cmd ) ?
1819+ xstrdup (busybox_path ) : NULL ;
1820+ }
1821+
17621822/*
17631823 * Determines the absolute path of cmd using the split path in path.
17641824 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1787,6 +1847,9 @@ static char *path_lookup(const char *cmd, int exe_only)
17871847 path = sep + 1 ;
17881848 }
17891849
1850+ if (!prog && !isexe )
1851+ prog = is_busybox_applet (cmd );
1852+
17901853 return prog ;
17911854}
17921855
@@ -1990,8 +2053,8 @@ static int is_msys2_sh(const char *cmd)
19902053}
19912054
19922055static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1993- const char * dir ,
1994- int prepend_cmd , int fhin , int fhout , int fherr )
2056+ const char * dir , const char * prepend_cmd ,
2057+ int fhin , int fhout , int fherr )
19952058{
19962059 STARTUPINFOEXW si ;
19972060 PROCESS_INFORMATION pi ;
@@ -2071,9 +2134,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20712134 /* concatenate argv, quoting args as we go */
20722135 strbuf_init (& args , 0 );
20732136 if (prepend_cmd ) {
2074- char * quoted = (char * )quote_arg (cmd );
2137+ char * quoted = (char * )quote_arg (prepend_cmd );
20752138 strbuf_addstr (& args , quoted );
2076- if (quoted != cmd )
2139+ if (quoted != prepend_cmd )
20772140 free (quoted );
20782141 }
20792142 for (; * argv ; argv ++ ) {
@@ -2193,7 +2256,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21932256 return (pid_t )pi .dwProcessId ;
21942257}
21952258
2196- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2259+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2260+ const char * prepend_cmd )
21972261{
21982262 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21992263}
@@ -2221,14 +2285,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
22212285 pid = -1 ;
22222286 }
22232287 else {
2224- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2288+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
22252289 fhin , fhout , fherr );
22262290 free (iprog );
22272291 }
22282292 argv [0 ] = argv0 ;
22292293 }
22302294 else
2231- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2295+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
22322296 fhin , fhout , fherr );
22332297 free (prog );
22342298 }
@@ -2253,7 +2317,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22532317 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22542318 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22552319 exec_id = trace2_exec (prog , (const char * * )argv2 );
2256- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2320+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22572321 if (pid >= 0 ) {
22582322 int status ;
22592323 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2277,7 +2341,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22772341 int exec_id ;
22782342
22792343 exec_id = trace2_exec (cmd , (const char * * )argv );
2280- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2344+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22812345 if (pid < 0 ) {
22822346 trace2_exec_result (exec_id , -1 );
22832347 return -1 ;
0 commit comments