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"
@@ -1926,6 +1927,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
19261927 return NULL ;
19271928}
19281929
1930+ static char * path_lookup (const char * cmd , int exe_only );
1931+
1932+ static char * is_busybox_applet (const char * cmd )
1933+ {
1934+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1935+ static char * busybox_path ;
1936+ static int busybox_path_initialized ;
1937+
1938+ /* Avoid infinite loop */
1939+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1940+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1941+ return NULL ;
1942+
1943+ if (!busybox_path_initialized ) {
1944+ busybox_path = path_lookup ("busybox.exe" , 1 );
1945+ busybox_path_initialized = 1 ;
1946+ }
1947+
1948+ /* Assume that sh is compiled in... */
1949+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1950+ return xstrdup_or_null (busybox_path );
1951+
1952+ if (!applets .nr ) {
1953+ struct child_process cp = CHILD_PROCESS_INIT ;
1954+ struct strbuf buf = STRBUF_INIT ;
1955+ char * p ;
1956+
1957+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1958+
1959+ if (capture_command (& cp , & buf , 2048 )) {
1960+ string_list_append (& applets , "" );
1961+ return NULL ;
1962+ }
1963+
1964+ /* parse output */
1965+ p = strstr (buf .buf , "Currently defined functions:\n" );
1966+ if (!p ) {
1967+ warning ("Could not parse output of busybox --help" );
1968+ string_list_append (& applets , "" );
1969+ return NULL ;
1970+ }
1971+ p = strchrnul (p , '\n' );
1972+ for (;;) {
1973+ size_t len ;
1974+
1975+ p += strspn (p , "\n\t ," );
1976+ len = strcspn (p , "\n\t ," );
1977+ if (!len )
1978+ break ;
1979+ p [len ] = '\0' ;
1980+ string_list_insert (& applets , p );
1981+ p = p + len + 1 ;
1982+ }
1983+ }
1984+
1985+ return string_list_has_string (& applets , cmd ) ?
1986+ xstrdup (busybox_path ) : NULL ;
1987+ }
1988+
19291989/*
19301990 * Determines the absolute path of cmd using the split path in path.
19311991 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1954,6 +2014,9 @@ static char *path_lookup(const char *cmd, int exe_only)
19542014 path = sep + 1 ;
19552015 }
19562016
2017+ if (!prog && !isexe )
2018+ prog = is_busybox_applet (cmd );
2019+
19572020 return prog ;
19582021}
19592022
@@ -2157,8 +2220,8 @@ static int is_msys2_sh(const char *cmd)
21572220}
21582221
21592222static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
2160- const char * dir ,
2161- int prepend_cmd , int fhin , int fhout , int fherr )
2223+ const char * dir , const char * prepend_cmd ,
2224+ int fhin , int fhout , int fherr )
21622225{
21632226 STARTUPINFOEXW si ;
21642227 PROCESS_INFORMATION pi ;
@@ -2238,9 +2301,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
22382301 /* concatenate argv, quoting args as we go */
22392302 strbuf_init (& args , 0 );
22402303 if (prepend_cmd ) {
2241- char * quoted = (char * )quote_arg (cmd );
2304+ char * quoted = (char * )quote_arg (prepend_cmd );
22422305 strbuf_addstr (& args , quoted );
2243- if (quoted != cmd )
2306+ if (quoted != prepend_cmd )
22442307 free (quoted );
22452308 }
22462309 for (; * argv ; argv ++ ) {
@@ -2360,7 +2423,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
23602423 return (pid_t )pi .dwProcessId ;
23612424}
23622425
2363- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2426+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2427+ const char * prepend_cmd )
23642428{
23652429 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
23662430}
@@ -2388,14 +2452,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
23882452 pid = -1 ;
23892453 }
23902454 else {
2391- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2455+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
23922456 fhin , fhout , fherr );
23932457 free (iprog );
23942458 }
23952459 argv [0 ] = argv0 ;
23962460 }
23972461 else
2398- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2462+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
23992463 fhin , fhout , fherr );
24002464 free (prog );
24012465 }
@@ -2420,7 +2484,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
24202484 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
24212485 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
24222486 exec_id = trace2_exec (prog , (const char * * )argv2 );
2423- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2487+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
24242488 if (pid >= 0 ) {
24252489 int status ;
24262490 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2444,7 +2508,7 @@ int mingw_execv(const char *cmd, char *const *argv)
24442508 int exec_id ;
24452509
24462510 exec_id = trace2_exec (cmd , (const char * * )argv );
2447- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2511+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
24482512 if (pid < 0 ) {
24492513 trace2_exec_result (exec_id , -1 );
24502514 return -1 ;
0 commit comments