2525#include "../repository.h"
2626#include "win32/fscache.h"
2727#include "../attr.h"
28+ #include "../string-list.h"
2829
2930#define HCAST (type , handle ) ((type)(intptr_t)handle)
3031
@@ -1734,6 +1735,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
17341735 return NULL ;
17351736}
17361737
1738+ static char * path_lookup (const char * cmd , int exe_only );
1739+
1740+ static char * is_busybox_applet (const char * cmd )
1741+ {
1742+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1743+ static char * busybox_path ;
1744+ static int busybox_path_initialized ;
1745+
1746+ /* Avoid infinite loop */
1747+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1748+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1749+ return NULL ;
1750+
1751+ if (!busybox_path_initialized ) {
1752+ busybox_path = path_lookup ("busybox.exe" , 1 );
1753+ busybox_path_initialized = 1 ;
1754+ }
1755+
1756+ /* Assume that sh is compiled in... */
1757+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1758+ return xstrdup_or_null (busybox_path );
1759+
1760+ if (!applets .nr ) {
1761+ struct child_process cp = CHILD_PROCESS_INIT ;
1762+ struct strbuf buf = STRBUF_INIT ;
1763+ char * p ;
1764+
1765+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1766+
1767+ if (capture_command (& cp , & buf , 2048 )) {
1768+ string_list_append (& applets , "" );
1769+ return NULL ;
1770+ }
1771+
1772+ /* parse output */
1773+ p = strstr (buf .buf , "Currently defined functions:\n" );
1774+ if (!p ) {
1775+ warning ("Could not parse output of busybox --help" );
1776+ string_list_append (& applets , "" );
1777+ return NULL ;
1778+ }
1779+ p = strchrnul (p , '\n' );
1780+ for (;;) {
1781+ size_t len ;
1782+
1783+ p += strspn (p , "\n\t ," );
1784+ len = strcspn (p , "\n\t ," );
1785+ if (!len )
1786+ break ;
1787+ p [len ] = '\0' ;
1788+ string_list_insert (& applets , p );
1789+ p = p + len + 1 ;
1790+ }
1791+ }
1792+
1793+ return string_list_has_string (& applets , cmd ) ?
1794+ xstrdup (busybox_path ) : NULL ;
1795+ }
1796+
17371797/*
17381798 * Determines the absolute path of cmd using the split path in path.
17391799 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1762,6 +1822,9 @@ static char *path_lookup(const char *cmd, int exe_only)
17621822 path = sep + 1 ;
17631823 }
17641824
1825+ if (!prog && !isexe )
1826+ prog = is_busybox_applet (cmd );
1827+
17651828 return prog ;
17661829}
17671830
@@ -1965,8 +2028,8 @@ static int is_msys2_sh(const char *cmd)
19652028}
19662029
19672030static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1968- const char * dir ,
1969- int prepend_cmd , int fhin , int fhout , int fherr )
2031+ const char * dir , const char * prepend_cmd ,
2032+ int fhin , int fhout , int fherr )
19702033{
19712034 static int restrict_handle_inheritance = -1 ;
19722035 STARTUPINFOEXW si ;
@@ -2057,9 +2120,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
20572120 /* concatenate argv, quoting args as we go */
20582121 strbuf_init (& args , 0 );
20592122 if (prepend_cmd ) {
2060- char * quoted = (char * )quote_arg (cmd );
2123+ char * quoted = (char * )quote_arg (prepend_cmd );
20612124 strbuf_addstr (& args , quoted );
2062- if (quoted != cmd )
2125+ if (quoted != prepend_cmd )
20632126 free (quoted );
20642127 }
20652128 for (; * argv ; argv ++ ) {
@@ -2218,7 +2281,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
22182281 return (pid_t )pi .dwProcessId ;
22192282}
22202283
2221- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2284+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2285+ const char * prepend_cmd )
22222286{
22232287 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
22242288}
@@ -2246,14 +2310,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
22462310 pid = -1 ;
22472311 }
22482312 else {
2249- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2313+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
22502314 fhin , fhout , fherr );
22512315 free (iprog );
22522316 }
22532317 argv [0 ] = argv0 ;
22542318 }
22552319 else
2256- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2320+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
22572321 fhin , fhout , fherr );
22582322 free (prog );
22592323 }
@@ -2278,7 +2342,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
22782342 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
22792343 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
22802344 exec_id = trace2_exec (prog , (const char * * )argv2 );
2281- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2345+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
22822346 if (pid >= 0 ) {
22832347 int status ;
22842348 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2302,7 +2366,7 @@ int mingw_execv(const char *cmd, char *const *argv)
23022366 int exec_id ;
23032367
23042368 exec_id = trace2_exec (cmd , (const char * * )argv );
2305- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2369+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
23062370 if (pid < 0 ) {
23072371 trace2_exec_result (exec_id , -1 );
23082372 return -1 ;
0 commit comments