23
23
#include "../repository.h"
24
24
#include "win32/fscache.h"
25
25
#include "../attr.h"
26
+ #include "../string-list.h"
26
27
27
28
#define HCAST (type , handle ) ((type)(intptr_t)handle)
28
29
@@ -1651,6 +1652,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
1651
1652
return NULL ;
1652
1653
}
1653
1654
1655
+ static char * path_lookup (const char * cmd , int exe_only );
1656
+
1657
+ static char * is_busybox_applet (const char * cmd )
1658
+ {
1659
+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1660
+ static char * busybox_path ;
1661
+ static int busybox_path_initialized ;
1662
+
1663
+ /* Avoid infinite loop */
1664
+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1665
+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1666
+ return NULL ;
1667
+
1668
+ if (!busybox_path_initialized ) {
1669
+ busybox_path = path_lookup ("busybox.exe" , 1 );
1670
+ busybox_path_initialized = 1 ;
1671
+ }
1672
+
1673
+ /* Assume that sh is compiled in... */
1674
+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1675
+ return xstrdup_or_null (busybox_path );
1676
+
1677
+ if (!applets .nr ) {
1678
+ struct child_process cp = CHILD_PROCESS_INIT ;
1679
+ struct strbuf buf = STRBUF_INIT ;
1680
+ char * p ;
1681
+
1682
+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1683
+
1684
+ if (capture_command (& cp , & buf , 2048 )) {
1685
+ string_list_append (& applets , "" );
1686
+ return NULL ;
1687
+ }
1688
+
1689
+ /* parse output */
1690
+ p = strstr (buf .buf , "Currently defined functions:\n" );
1691
+ if (!p ) {
1692
+ warning ("Could not parse output of busybox --help" );
1693
+ string_list_append (& applets , "" );
1694
+ return NULL ;
1695
+ }
1696
+ p = strchrnul (p , '\n' );
1697
+ for (;;) {
1698
+ size_t len ;
1699
+
1700
+ p += strspn (p , "\n\t ," );
1701
+ len = strcspn (p , "\n\t ," );
1702
+ if (!len )
1703
+ break ;
1704
+ p [len ] = '\0' ;
1705
+ string_list_insert (& applets , p );
1706
+ p = p + len + 1 ;
1707
+ }
1708
+ }
1709
+
1710
+ return string_list_has_string (& applets , cmd ) ?
1711
+ xstrdup (busybox_path ) : NULL ;
1712
+ }
1713
+
1654
1714
/*
1655
1715
* Determines the absolute path of cmd using the split path in path.
1656
1716
* If cmd contains a slash or backslash, no lookup is performed.
@@ -1679,6 +1739,9 @@ static char *path_lookup(const char *cmd, int exe_only)
1679
1739
path = sep + 1 ;
1680
1740
}
1681
1741
1742
+ if (!prog && !isexe )
1743
+ prog = is_busybox_applet (cmd );
1744
+
1682
1745
return prog ;
1683
1746
}
1684
1747
@@ -1882,8 +1945,8 @@ static int is_msys2_sh(const char *cmd)
1882
1945
}
1883
1946
1884
1947
static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1885
- const char * dir ,
1886
- int prepend_cmd , int fhin , int fhout , int fherr )
1948
+ const char * dir , const char * prepend_cmd ,
1949
+ int fhin , int fhout , int fherr )
1887
1950
{
1888
1951
static int restrict_handle_inheritance = -1 ;
1889
1952
STARTUPINFOEXW si ;
@@ -1974,9 +2037,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
1974
2037
/* concatenate argv, quoting args as we go */
1975
2038
strbuf_init (& args , 0 );
1976
2039
if (prepend_cmd ) {
1977
- char * quoted = (char * )quote_arg (cmd );
2040
+ char * quoted = (char * )quote_arg (prepend_cmd );
1978
2041
strbuf_addstr (& args , quoted );
1979
- if (quoted != cmd )
2042
+ if (quoted != prepend_cmd )
1980
2043
free (quoted );
1981
2044
}
1982
2045
for (; * argv ; argv ++ ) {
@@ -2135,7 +2198,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2135
2198
return (pid_t )pi .dwProcessId ;
2136
2199
}
2137
2200
2138
- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2201
+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2202
+ const char * prepend_cmd )
2139
2203
{
2140
2204
return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
2141
2205
}
@@ -2163,14 +2227,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
2163
2227
pid = -1 ;
2164
2228
}
2165
2229
else {
2166
- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2230
+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
2167
2231
fhin , fhout , fherr );
2168
2232
free (iprog );
2169
2233
}
2170
2234
argv [0 ] = argv0 ;
2171
2235
}
2172
2236
else
2173
- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2237
+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
2174
2238
fhin , fhout , fherr );
2175
2239
free (prog );
2176
2240
}
@@ -2195,7 +2259,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
2195
2259
argv2 [0 ] = (char * )cmd ; /* full path to the script file */
2196
2260
COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
2197
2261
exec_id = trace2_exec (prog , (const char * * )argv2 );
2198
- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2262
+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
2199
2263
if (pid >= 0 ) {
2200
2264
int status ;
2201
2265
if (waitpid (pid , & status , 0 ) < 0 )
@@ -2219,7 +2283,7 @@ int mingw_execv(const char *cmd, char *const *argv)
2219
2283
int exec_id ;
2220
2284
2221
2285
exec_id = trace2_exec (cmd , (const char * * )argv );
2222
- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2286
+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
2223
2287
if (pid < 0 ) {
2224
2288
trace2_exec_result (exec_id , -1 );
2225
2289
return -1 ;
0 commit comments