26
26
#include "../repository.h"
27
27
#include "win32/fscache.h"
28
28
#include "../attr.h"
29
+ #include "../string-list.h"
29
30
30
31
#define HCAST (type , handle ) ((type)(intptr_t)handle)
31
32
@@ -1746,6 +1747,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
1746
1747
return NULL ;
1747
1748
}
1748
1749
1750
+ static char * path_lookup (const char * cmd , int exe_only );
1751
+
1752
+ static char * is_busybox_applet (const char * cmd )
1753
+ {
1754
+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1755
+ static char * busybox_path ;
1756
+ static int busybox_path_initialized ;
1757
+
1758
+ /* Avoid infinite loop */
1759
+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1760
+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1761
+ return NULL ;
1762
+
1763
+ if (!busybox_path_initialized ) {
1764
+ busybox_path = path_lookup ("busybox.exe" , 1 );
1765
+ busybox_path_initialized = 1 ;
1766
+ }
1767
+
1768
+ /* Assume that sh is compiled in... */
1769
+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1770
+ return xstrdup_or_null (busybox_path );
1771
+
1772
+ if (!applets .nr ) {
1773
+ struct child_process cp = CHILD_PROCESS_INIT ;
1774
+ struct strbuf buf = STRBUF_INIT ;
1775
+ char * p ;
1776
+
1777
+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1778
+
1779
+ if (capture_command (& cp , & buf , 2048 )) {
1780
+ string_list_append (& applets , "" );
1781
+ return NULL ;
1782
+ }
1783
+
1784
+ /* parse output */
1785
+ p = strstr (buf .buf , "Currently defined functions:\n" );
1786
+ if (!p ) {
1787
+ warning ("Could not parse output of busybox --help" );
1788
+ string_list_append (& applets , "" );
1789
+ return NULL ;
1790
+ }
1791
+ p = strchrnul (p , '\n' );
1792
+ for (;;) {
1793
+ size_t len ;
1794
+
1795
+ p += strspn (p , "\n\t ," );
1796
+ len = strcspn (p , "\n\t ," );
1797
+ if (!len )
1798
+ break ;
1799
+ p [len ] = '\0' ;
1800
+ string_list_insert (& applets , p );
1801
+ p = p + len + 1 ;
1802
+ }
1803
+ }
1804
+
1805
+ return string_list_has_string (& applets , cmd ) ?
1806
+ xstrdup (busybox_path ) : NULL ;
1807
+ }
1808
+
1749
1809
/*
1750
1810
* Determines the absolute path of cmd using the split path in path.
1751
1811
* If cmd contains a slash or backslash, no lookup is performed.
@@ -1774,6 +1834,9 @@ static char *path_lookup(const char *cmd, int exe_only)
1774
1834
path = sep + 1 ;
1775
1835
}
1776
1836
1837
+ if (!prog && !isexe )
1838
+ prog = is_busybox_applet (cmd );
1839
+
1777
1840
return prog ;
1778
1841
}
1779
1842
@@ -1977,8 +2040,8 @@ static int is_msys2_sh(const char *cmd)
1977
2040
}
1978
2041
1979
2042
static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1980
- const char * dir ,
1981
- int prepend_cmd , int fhin , int fhout , int fherr )
2043
+ const char * dir , const char * prepend_cmd ,
2044
+ int fhin , int fhout , int fherr )
1982
2045
{
1983
2046
static int restrict_handle_inheritance = -1 ;
1984
2047
STARTUPINFOEXW si ;
@@ -2069,9 +2132,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2069
2132
/* concatenate argv, quoting args as we go */
2070
2133
strbuf_init (& args , 0 );
2071
2134
if (prepend_cmd ) {
2072
- char * quoted = (char * )quote_arg (cmd );
2135
+ char * quoted = (char * )quote_arg (prepend_cmd );
2073
2136
strbuf_addstr (& args , quoted );
2074
- if (quoted != cmd )
2137
+ if (quoted != prepend_cmd )
2075
2138
free (quoted );
2076
2139
}
2077
2140
for (; * argv ; argv ++ ) {
@@ -2230,7 +2293,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2230
2293
return (pid_t )pi .dwProcessId ;
2231
2294
}
2232
2295
2233
- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2296
+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2297
+ const char * prepend_cmd )
2234
2298
{
2235
2299
return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
2236
2300
}
@@ -2258,14 +2322,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
2258
2322
pid = -1 ;
2259
2323
}
2260
2324
else {
2261
- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2325
+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
2262
2326
fhin , fhout , fherr );
2263
2327
free (iprog );
2264
2328
}
2265
2329
argv [0 ] = argv0 ;
2266
2330
}
2267
2331
else
2268
- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2332
+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
2269
2333
fhin , fhout , fherr );
2270
2334
free (prog );
2271
2335
}
@@ -2290,7 +2354,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
2290
2354
argv2 [0 ] = (char * )cmd ; /* full path to the script file */
2291
2355
COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
2292
2356
exec_id = trace2_exec (prog , (const char * * )argv2 );
2293
- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2357
+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
2294
2358
if (pid >= 0 ) {
2295
2359
int status ;
2296
2360
if (waitpid (pid , & status , 0 ) < 0 )
@@ -2314,7 +2378,7 @@ int mingw_execv(const char *cmd, char *const *argv)
2314
2378
int exec_id ;
2315
2379
2316
2380
exec_id = trace2_exec (cmd , (const char * * )argv );
2317
- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2381
+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
2318
2382
if (pid < 0 ) {
2319
2383
trace2_exec_result (exec_id , -1 );
2320
2384
return -1 ;
0 commit comments