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"
@@ -1842,6 +1843,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
18421843 return NULL ;
18431844}
18441845
1846+ static char * path_lookup (const char * cmd , int exe_only );
1847+
1848+ static char * is_busybox_applet (const char * cmd )
1849+ {
1850+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1851+ static char * busybox_path ;
1852+ static int busybox_path_initialized ;
1853+
1854+ /* Avoid infinite loop */
1855+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1856+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1857+ return NULL ;
1858+
1859+ if (!busybox_path_initialized ) {
1860+ busybox_path = path_lookup ("busybox.exe" , 1 );
1861+ busybox_path_initialized = 1 ;
1862+ }
1863+
1864+ /* Assume that sh is compiled in... */
1865+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1866+ return xstrdup_or_null (busybox_path );
1867+
1868+ if (!applets .nr ) {
1869+ struct child_process cp = CHILD_PROCESS_INIT ;
1870+ struct strbuf buf = STRBUF_INIT ;
1871+ char * p ;
1872+
1873+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1874+
1875+ if (capture_command (& cp , & buf , 2048 )) {
1876+ string_list_append (& applets , "" );
1877+ return NULL ;
1878+ }
1879+
1880+ /* parse output */
1881+ p = strstr (buf .buf , "Currently defined functions:\n" );
1882+ if (!p ) {
1883+ warning ("Could not parse output of busybox --help" );
1884+ string_list_append (& applets , "" );
1885+ return NULL ;
1886+ }
1887+ p = strchrnul (p , '\n' );
1888+ for (;;) {
1889+ size_t len ;
1890+
1891+ p += strspn (p , "\n\t ," );
1892+ len = strcspn (p , "\n\t ," );
1893+ if (!len )
1894+ break ;
1895+ p [len ] = '\0' ;
1896+ string_list_insert (& applets , p );
1897+ p = p + len + 1 ;
1898+ }
1899+ }
1900+
1901+ return string_list_has_string (& applets , cmd ) ?
1902+ xstrdup (busybox_path ) : NULL ;
1903+ }
1904+
18451905/*
18461906 * Determines the absolute path of cmd using the split path in path.
18471907 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1870,6 +1930,9 @@ static char *path_lookup(const char *cmd, int exe_only)
18701930 path = sep + 1 ;
18711931 }
18721932
1933+ if (!prog && !isexe )
1934+ prog = is_busybox_applet (cmd );
1935+
18731936 return prog ;
18741937}
18751938
@@ -2073,8 +2136,8 @@ static int is_msys2_sh(const char *cmd)
20732136}
20742137
20752138static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
2076- const char * dir ,
2077- int prepend_cmd , int fhin , int fhout , int fherr )
2139+ const char * dir , const char * prepend_cmd ,
2140+ int fhin , int fhout , int fherr )
20782141{
20792142 STARTUPINFOEXW si ;
20802143 PROCESS_INFORMATION pi ;
@@ -2154,9 +2217,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21542217 /* concatenate argv, quoting args as we go */
21552218 strbuf_init (& args , 0 );
21562219 if (prepend_cmd ) {
2157- char * quoted = (char * )quote_arg (cmd );
2220+ char * quoted = (char * )quote_arg (prepend_cmd );
21582221 strbuf_addstr (& args , quoted );
2159- if (quoted != cmd )
2222+ if (quoted != prepend_cmd )
21602223 free (quoted );
21612224 }
21622225 for (; * argv ; argv ++ ) {
@@ -2276,7 +2339,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
22762339 return (pid_t )pi .dwProcessId ;
22772340}
22782341
2279- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2342+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2343+ const char * prepend_cmd )
22802344{
22812345 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
22822346}
@@ -2304,14 +2368,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
23042368 pid = -1 ;
23052369 }
23062370 else {
2307- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2371+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
23082372 fhin , fhout , fherr );
23092373 free (iprog );
23102374 }
23112375 argv [0 ] = argv0 ;
23122376 }
23132377 else
2314- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2378+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
23152379 fhin , fhout , fherr );
23162380 free (prog );
23172381 }
@@ -2336,7 +2400,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
23362400 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
23372401 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
23382402 exec_id = trace2_exec (prog , (const char * * )argv2 );
2339- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2403+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
23402404 if (pid >= 0 ) {
23412405 int status ;
23422406 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2360,7 +2424,7 @@ int mingw_execv(const char *cmd, char *const *argv)
23602424 int exec_id ;
23612425
23622426 exec_id = trace2_exec (cmd , (const char * * )argv );
2363- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2427+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
23642428 if (pid < 0 ) {
23652429 trace2_exec_result (exec_id , -1 );
23662430 return -1 ;
0 commit comments