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"
@@ -1869,6 +1870,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
18691870 return NULL ;
18701871}
18711872
1873+ static char * path_lookup (const char * cmd , int exe_only );
1874+
1875+ static char * is_busybox_applet (const char * cmd )
1876+ {
1877+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1878+ static char * busybox_path ;
1879+ static int busybox_path_initialized ;
1880+
1881+ /* Avoid infinite loop */
1882+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1883+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1884+ return NULL ;
1885+
1886+ if (!busybox_path_initialized ) {
1887+ busybox_path = path_lookup ("busybox.exe" , 1 );
1888+ busybox_path_initialized = 1 ;
1889+ }
1890+
1891+ /* Assume that sh is compiled in... */
1892+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1893+ return xstrdup_or_null (busybox_path );
1894+
1895+ if (!applets .nr ) {
1896+ struct child_process cp = CHILD_PROCESS_INIT ;
1897+ struct strbuf buf = STRBUF_INIT ;
1898+ char * p ;
1899+
1900+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1901+
1902+ if (capture_command (& cp , & buf , 2048 )) {
1903+ string_list_append (& applets , "" );
1904+ return NULL ;
1905+ }
1906+
1907+ /* parse output */
1908+ p = strstr (buf .buf , "Currently defined functions:\n" );
1909+ if (!p ) {
1910+ warning ("Could not parse output of busybox --help" );
1911+ string_list_append (& applets , "" );
1912+ return NULL ;
1913+ }
1914+ p = strchrnul (p , '\n' );
1915+ for (;;) {
1916+ size_t len ;
1917+
1918+ p += strspn (p , "\n\t ," );
1919+ len = strcspn (p , "\n\t ," );
1920+ if (!len )
1921+ break ;
1922+ p [len ] = '\0' ;
1923+ string_list_insert (& applets , p );
1924+ p = p + len + 1 ;
1925+ }
1926+ }
1927+
1928+ return string_list_has_string (& applets , cmd ) ?
1929+ xstrdup (busybox_path ) : NULL ;
1930+ }
1931+
18721932/*
18731933 * Determines the absolute path of cmd using the split path in path.
18741934 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1897,6 +1957,9 @@ static char *path_lookup(const char *cmd, int exe_only)
18971957 path = sep + 1 ;
18981958 }
18991959
1960+ if (!prog && !isexe )
1961+ prog = is_busybox_applet (cmd );
1962+
19001963 return prog ;
19011964}
19021965
@@ -2100,8 +2163,8 @@ static int is_msys2_sh(const char *cmd)
21002163}
21012164
21022165static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
2103- const char * dir ,
2104- int prepend_cmd , int fhin , int fhout , int fherr )
2166+ const char * dir , const char * prepend_cmd ,
2167+ int fhin , int fhout , int fherr )
21052168{
21062169 STARTUPINFOEXW si ;
21072170 PROCESS_INFORMATION pi ;
@@ -2181,9 +2244,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21812244 /* concatenate argv, quoting args as we go */
21822245 strbuf_init (& args , 0 );
21832246 if (prepend_cmd ) {
2184- char * quoted = (char * )quote_arg (cmd );
2247+ char * quoted = (char * )quote_arg (prepend_cmd );
21852248 strbuf_addstr (& args , quoted );
2186- if (quoted != cmd )
2249+ if (quoted != prepend_cmd )
21872250 free (quoted );
21882251 }
21892252 for (; * argv ; argv ++ ) {
@@ -2303,7 +2366,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
23032366 return (pid_t )pi .dwProcessId ;
23042367}
23052368
2306- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2369+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2370+ const char * prepend_cmd )
23072371{
23082372 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
23092373}
@@ -2331,14 +2395,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
23312395 pid = -1 ;
23322396 }
23332397 else {
2334- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2398+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
23352399 fhin , fhout , fherr );
23362400 free (iprog );
23372401 }
23382402 argv [0 ] = argv0 ;
23392403 }
23402404 else
2341- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2405+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
23422406 fhin , fhout , fherr );
23432407 free (prog );
23442408 }
@@ -2363,7 +2427,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
23632427 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
23642428 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
23652429 exec_id = trace2_exec (prog , (const char * * )argv2 );
2366- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2430+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
23672431 if (pid >= 0 ) {
23682432 int status ;
23692433 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2387,7 +2451,7 @@ int mingw_execv(const char *cmd, char *const *argv)
23872451 int exec_id ;
23882452
23892453 exec_id = trace2_exec (cmd , (const char * * )argv );
2390- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2454+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
23912455 if (pid < 0 ) {
23922456 trace2_exec_result (exec_id , -1 );
23932457 return -1 ;
0 commit comments