1212#include "repository.h"
1313#include "run-command.h"
1414#include "strbuf.h"
15+ #include "string-list.h"
1516#include "symlinks.h"
1617#include "trace2.h"
1718#include "win32.h"
@@ -1761,6 +1762,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
17611762 return NULL ;
17621763}
17631764
1765+ static char * path_lookup (const char * cmd , int exe_only );
1766+
1767+ static char * is_busybox_applet (const char * cmd )
1768+ {
1769+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1770+ static char * busybox_path ;
1771+ static int busybox_path_initialized ;
1772+
1773+ /* Avoid infinite loop */
1774+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1775+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1776+ return NULL ;
1777+
1778+ if (!busybox_path_initialized ) {
1779+ busybox_path = path_lookup ("busybox.exe" , 1 );
1780+ busybox_path_initialized = 1 ;
1781+ }
1782+
1783+ /* Assume that sh is compiled in... */
1784+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1785+ return xstrdup_or_null (busybox_path );
1786+
1787+ if (!applets .nr ) {
1788+ struct child_process cp = CHILD_PROCESS_INIT ;
1789+ struct strbuf buf = STRBUF_INIT ;
1790+ char * p ;
1791+
1792+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1793+
1794+ if (capture_command (& cp , & buf , 2048 )) {
1795+ string_list_append (& applets , "" );
1796+ return NULL ;
1797+ }
1798+
1799+ /* parse output */
1800+ p = strstr (buf .buf , "Currently defined functions:\n" );
1801+ if (!p ) {
1802+ warning ("Could not parse output of busybox --help" );
1803+ string_list_append (& applets , "" );
1804+ return NULL ;
1805+ }
1806+ p = strchrnul (p , '\n' );
1807+ for (;;) {
1808+ size_t len ;
1809+
1810+ p += strspn (p , "\n\t ," );
1811+ len = strcspn (p , "\n\t ," );
1812+ if (!len )
1813+ break ;
1814+ p [len ] = '\0' ;
1815+ string_list_insert (& applets , p );
1816+ p = p + len + 1 ;
1817+ }
1818+ }
1819+
1820+ return string_list_has_string (& applets , cmd ) ?
1821+ xstrdup (busybox_path ) : NULL ;
1822+ }
1823+
17641824/*
17651825 * Determines the absolute path of cmd using the split path in path.
17661826 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1789,6 +1849,9 @@ static char *path_lookup(const char *cmd, int exe_only)
17891849 path = sep + 1 ;
17901850 }
17911851
1852+ if (!prog && !isexe )
1853+ prog = is_busybox_applet (cmd );
1854+
17921855 return prog ;
17931856}
17941857
@@ -1992,8 +2055,8 @@ static int is_msys2_sh(const char *cmd)
19922055}
19932056
19942057static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1995- const char * dir ,
1996- int prepend_cmd , int fhin , int fhout , int fherr )
2058+ const char * dir , const char * prepend_cmd ,
2059+ int fhin , int fhout , int fherr )
19972060{
19982061 STARTUPINFOEXW si ;
19992062 PROCESS_INFORMATION pi ;
@@ -2073,9 +2136,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20732136 /* concatenate argv, quoting args as we go */
20742137 strbuf_init (& args , 0 );
20752138 if (prepend_cmd ) {
2076- char * quoted = (char * )quote_arg (cmd );
2139+ char * quoted = (char * )quote_arg (prepend_cmd );
20772140 strbuf_addstr (& args , quoted );
2078- if (quoted != cmd )
2141+ if (quoted != prepend_cmd )
20792142 free (quoted );
20802143 }
20812144 for (; * argv ; argv ++ ) {
@@ -2195,7 +2258,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21952258 return (pid_t )pi .dwProcessId ;
21962259}
21972260
2198- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2261+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2262+ const char * prepend_cmd )
21992263{
22002264 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
22012265}
@@ -2223,14 +2287,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
22232287 pid = -1 ;
22242288 }
22252289 else {
2226- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2290+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
22272291 fhin , fhout , fherr );
22282292 free (iprog );
22292293 }
22302294 argv [0 ] = argv0 ;
22312295 }
22322296 else
2233- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2297+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
22342298 fhin , fhout , fherr );
22352299 free (prog );
22362300 }
@@ -2255,7 +2319,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22552319 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22562320 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22572321 exec_id = trace2_exec (prog , (const char * * )argv2 );
2258- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2322+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22592323 if (pid >= 0 ) {
22602324 int status ;
22612325 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2279,7 +2343,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22792343 int exec_id ;
22802344
22812345 exec_id = trace2_exec (cmd , (const char * * )argv );
2282- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2346+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22832347 if (pid < 0 ) {
22842348 trace2_exec_result (exec_id , -1 );
22852349 return -1 ;
0 commit comments