25
25
#include "../repository.h"
26
26
#include "win32/fscache.h"
27
27
#include "../attr.h"
28
+ #include "../string-list.h"
28
29
29
30
#define HCAST (type , handle ) ((type)(intptr_t)handle)
30
31
@@ -1734,6 +1735,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
1734
1735
return NULL ;
1735
1736
}
1736
1737
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
+
1737
1797
/*
1738
1798
* Determines the absolute path of cmd using the split path in path.
1739
1799
* 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)
1762
1822
path = sep + 1 ;
1763
1823
}
1764
1824
1825
+ if (!prog && !isexe )
1826
+ prog = is_busybox_applet (cmd );
1827
+
1765
1828
return prog ;
1766
1829
}
1767
1830
@@ -1965,8 +2028,8 @@ static int is_msys2_sh(const char *cmd)
1965
2028
}
1966
2029
1967
2030
static 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 )
1970
2033
{
1971
2034
static int restrict_handle_inheritance = -1 ;
1972
2035
STARTUPINFOEXW si ;
@@ -2057,9 +2120,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2057
2120
/* concatenate argv, quoting args as we go */
2058
2121
strbuf_init (& args , 0 );
2059
2122
if (prepend_cmd ) {
2060
- char * quoted = (char * )quote_arg (cmd );
2123
+ char * quoted = (char * )quote_arg (prepend_cmd );
2061
2124
strbuf_addstr (& args , quoted );
2062
- if (quoted != cmd )
2125
+ if (quoted != prepend_cmd )
2063
2126
free (quoted );
2064
2127
}
2065
2128
for (; * argv ; argv ++ ) {
@@ -2218,7 +2281,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2218
2281
return (pid_t )pi .dwProcessId ;
2219
2282
}
2220
2283
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 )
2222
2286
{
2223
2287
return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
2224
2288
}
@@ -2246,14 +2310,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
2246
2310
pid = -1 ;
2247
2311
}
2248
2312
else {
2249
- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2313
+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
2250
2314
fhin , fhout , fherr );
2251
2315
free (iprog );
2252
2316
}
2253
2317
argv [0 ] = argv0 ;
2254
2318
}
2255
2319
else
2256
- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2320
+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
2257
2321
fhin , fhout , fherr );
2258
2322
free (prog );
2259
2323
}
@@ -2278,7 +2342,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
2278
2342
argv2 [0 ] = (char * )cmd ; /* full path to the script file */
2279
2343
COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
2280
2344
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 );
2282
2346
if (pid >= 0 ) {
2283
2347
int status ;
2284
2348
if (waitpid (pid , & status , 0 ) < 0 )
@@ -2302,7 +2366,7 @@ int mingw_execv(const char *cmd, char *const *argv)
2302
2366
int exec_id ;
2303
2367
2304
2368
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 );
2306
2370
if (pid < 0 ) {
2307
2371
trace2_exec_result (exec_id , -1 );
2308
2372
return -1 ;
0 commit comments