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