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"
@@ -1912,6 +1913,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
19121913 return NULL ;
19131914}
19141915
1916+ static char * path_lookup (const char * cmd , int exe_only );
1917+
1918+ static char * is_busybox_applet (const char * cmd )
1919+ {
1920+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1921+ static char * busybox_path ;
1922+ static int busybox_path_initialized ;
1923+
1924+ /* Avoid infinite loop */
1925+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1926+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1927+ return NULL ;
1928+
1929+ if (!busybox_path_initialized ) {
1930+ busybox_path = path_lookup ("busybox.exe" , 1 );
1931+ busybox_path_initialized = 1 ;
1932+ }
1933+
1934+ /* Assume that sh is compiled in... */
1935+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1936+ return xstrdup_or_null (busybox_path );
1937+
1938+ if (!applets .nr ) {
1939+ struct child_process cp = CHILD_PROCESS_INIT ;
1940+ struct strbuf buf = STRBUF_INIT ;
1941+ char * p ;
1942+
1943+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1944+
1945+ if (capture_command (& cp , & buf , 2048 )) {
1946+ string_list_append (& applets , "" );
1947+ return NULL ;
1948+ }
1949+
1950+ /* parse output */
1951+ p = strstr (buf .buf , "Currently defined functions:\n" );
1952+ if (!p ) {
1953+ warning ("Could not parse output of busybox --help" );
1954+ string_list_append (& applets , "" );
1955+ return NULL ;
1956+ }
1957+ p = strchrnul (p , '\n' );
1958+ for (;;) {
1959+ size_t len ;
1960+
1961+ p += strspn (p , "\n\t ," );
1962+ len = strcspn (p , "\n\t ," );
1963+ if (!len )
1964+ break ;
1965+ p [len ] = '\0' ;
1966+ string_list_insert (& applets , p );
1967+ p = p + len + 1 ;
1968+ }
1969+ }
1970+
1971+ return string_list_has_string (& applets , cmd ) ?
1972+ xstrdup (busybox_path ) : NULL ;
1973+ }
1974+
19151975/*
19161976 * Determines the absolute path of cmd using the split path in path.
19171977 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1940,6 +2000,9 @@ static char *path_lookup(const char *cmd, int exe_only)
19402000 path = sep + 1 ;
19412001 }
19422002
2003+ if (!prog && !isexe )
2004+ prog = is_busybox_applet (cmd );
2005+
19432006 return prog ;
19442007}
19452008
@@ -2143,8 +2206,8 @@ static int is_msys2_sh(const char *cmd)
21432206}
21442207
21452208static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
2146- const char * dir ,
2147- int prepend_cmd , int fhin , int fhout , int fherr )
2209+ const char * dir , const char * prepend_cmd ,
2210+ int fhin , int fhout , int fherr )
21482211{
21492212 STARTUPINFOEXW si ;
21502213 PROCESS_INFORMATION pi ;
@@ -2224,9 +2287,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
22242287 /* concatenate argv, quoting args as we go */
22252288 strbuf_init (& args , 0 );
22262289 if (prepend_cmd ) {
2227- char * quoted = (char * )quote_arg (cmd );
2290+ char * quoted = (char * )quote_arg (prepend_cmd );
22282291 strbuf_addstr (& args , quoted );
2229- if (quoted != cmd )
2292+ if (quoted != prepend_cmd )
22302293 free (quoted );
22312294 }
22322295 for (; * argv ; argv ++ ) {
@@ -2346,7 +2409,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
23462409 return (pid_t )pi .dwProcessId ;
23472410}
23482411
2349- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2412+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2413+ const char * prepend_cmd )
23502414{
23512415 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
23522416}
@@ -2374,14 +2438,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
23742438 pid = -1 ;
23752439 }
23762440 else {
2377- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2441+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
23782442 fhin , fhout , fherr );
23792443 free (iprog );
23802444 }
23812445 argv [0 ] = argv0 ;
23822446 }
23832447 else
2384- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2448+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
23852449 fhin , fhout , fherr );
23862450 free (prog );
23872451 }
@@ -2406,7 +2470,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
24062470 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
24072471 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
24082472 exec_id = trace2_exec (prog , (const char * * )argv2 );
2409- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2473+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
24102474 if (pid >= 0 ) {
24112475 int status ;
24122476 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2430,7 +2494,7 @@ int mingw_execv(const char *cmd, char *const *argv)
24302494 int exec_id ;
24312495
24322496 exec_id = trace2_exec (cmd , (const char * * )argv );
2433- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2497+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
24342498 if (pid < 0 ) {
24352499 trace2_exec_result (exec_id , -1 );
24362500 return -1 ;
0 commit comments