12
12
#include "repository.h"
13
13
#include "run-command.h"
14
14
#include "strbuf.h"
15
+ #include "string-list.h"
15
16
#include "symlinks.h"
16
17
#include "trace2.h"
17
18
#include "win32.h"
@@ -1761,6 +1762,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
1761
1762
return NULL ;
1762
1763
}
1763
1764
1765
+ static char * path_lookup (const char * cmd , int exe_only );
1766
+
1767
+ static char * is_busybox_applet (const char * cmd )
1768
+ {
1769
+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1770
+ static char * busybox_path ;
1771
+ static int busybox_path_initialized ;
1772
+
1773
+ /* Avoid infinite loop */
1774
+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1775
+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1776
+ return NULL ;
1777
+
1778
+ if (!busybox_path_initialized ) {
1779
+ busybox_path = path_lookup ("busybox.exe" , 1 );
1780
+ busybox_path_initialized = 1 ;
1781
+ }
1782
+
1783
+ /* Assume that sh is compiled in... */
1784
+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1785
+ return xstrdup_or_null (busybox_path );
1786
+
1787
+ if (!applets .nr ) {
1788
+ struct child_process cp = CHILD_PROCESS_INIT ;
1789
+ struct strbuf buf = STRBUF_INIT ;
1790
+ char * p ;
1791
+
1792
+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1793
+
1794
+ if (capture_command (& cp , & buf , 2048 )) {
1795
+ string_list_append (& applets , "" );
1796
+ return NULL ;
1797
+ }
1798
+
1799
+ /* parse output */
1800
+ p = strstr (buf .buf , "Currently defined functions:\n" );
1801
+ if (!p ) {
1802
+ warning ("Could not parse output of busybox --help" );
1803
+ string_list_append (& applets , "" );
1804
+ return NULL ;
1805
+ }
1806
+ p = strchrnul (p , '\n' );
1807
+ for (;;) {
1808
+ size_t len ;
1809
+
1810
+ p += strspn (p , "\n\t ," );
1811
+ len = strcspn (p , "\n\t ," );
1812
+ if (!len )
1813
+ break ;
1814
+ p [len ] = '\0' ;
1815
+ string_list_insert (& applets , p );
1816
+ p = p + len + 1 ;
1817
+ }
1818
+ }
1819
+
1820
+ return string_list_has_string (& applets , cmd ) ?
1821
+ xstrdup (busybox_path ) : NULL ;
1822
+ }
1823
+
1764
1824
/*
1765
1825
* Determines the absolute path of cmd using the split path in path.
1766
1826
* If cmd contains a slash or backslash, no lookup is performed.
@@ -1789,6 +1849,9 @@ static char *path_lookup(const char *cmd, int exe_only)
1789
1849
path = sep + 1 ;
1790
1850
}
1791
1851
1852
+ if (!prog && !isexe )
1853
+ prog = is_busybox_applet (cmd );
1854
+
1792
1855
return prog ;
1793
1856
}
1794
1857
@@ -1992,8 +2055,8 @@ static int is_msys2_sh(const char *cmd)
1992
2055
}
1993
2056
1994
2057
static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1995
- const char * dir ,
1996
- int prepend_cmd , int fhin , int fhout , int fherr )
2058
+ const char * dir , const char * prepend_cmd ,
2059
+ int fhin , int fhout , int fherr )
1997
2060
{
1998
2061
STARTUPINFOEXW si ;
1999
2062
PROCESS_INFORMATION pi ;
@@ -2073,9 +2136,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2073
2136
/* concatenate argv, quoting args as we go */
2074
2137
strbuf_init (& args , 0 );
2075
2138
if (prepend_cmd ) {
2076
- char * quoted = (char * )quote_arg (cmd );
2139
+ char * quoted = (char * )quote_arg (prepend_cmd );
2077
2140
strbuf_addstr (& args , quoted );
2078
- if (quoted != cmd )
2141
+ if (quoted != prepend_cmd )
2079
2142
free (quoted );
2080
2143
}
2081
2144
for (; * argv ; argv ++ ) {
@@ -2195,7 +2258,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2195
2258
return (pid_t )pi .dwProcessId ;
2196
2259
}
2197
2260
2198
- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2261
+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2262
+ const char * prepend_cmd )
2199
2263
{
2200
2264
return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
2201
2265
}
@@ -2223,14 +2287,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
2223
2287
pid = -1 ;
2224
2288
}
2225
2289
else {
2226
- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2290
+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
2227
2291
fhin , fhout , fherr );
2228
2292
free (iprog );
2229
2293
}
2230
2294
argv [0 ] = argv0 ;
2231
2295
}
2232
2296
else
2233
- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2297
+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
2234
2298
fhin , fhout , fherr );
2235
2299
free (prog );
2236
2300
}
@@ -2255,7 +2319,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
2255
2319
argv2 [0 ] = (char * )cmd ; /* full path to the script file */
2256
2320
COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
2257
2321
exec_id = trace2_exec (prog , (const char * * )argv2 );
2258
- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2322
+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
2259
2323
if (pid >= 0 ) {
2260
2324
int status ;
2261
2325
if (waitpid (pid , & status , 0 ) < 0 )
@@ -2279,7 +2343,7 @@ int mingw_execv(const char *cmd, char *const *argv)
2279
2343
int exec_id ;
2280
2344
2281
2345
exec_id = trace2_exec (cmd , (const char * * )argv );
2282
- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2346
+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
2283
2347
if (pid < 0 ) {
2284
2348
trace2_exec_result (exec_id , -1 );
2285
2349
return -1 ;
0 commit comments