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
@@ -1665,6 +1666,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
1665
1666
return NULL ;
1666
1667
}
1667
1668
1669
+ static char * path_lookup (const char * cmd , int exe_only );
1670
+
1671
+ static char * is_busybox_applet (const char * cmd )
1672
+ {
1673
+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1674
+ static char * busybox_path ;
1675
+ static int busybox_path_initialized ;
1676
+
1677
+ /* Avoid infinite loop */
1678
+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1679
+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1680
+ return NULL ;
1681
+
1682
+ if (!busybox_path_initialized ) {
1683
+ busybox_path = path_lookup ("busybox.exe" , 1 );
1684
+ busybox_path_initialized = 1 ;
1685
+ }
1686
+
1687
+ /* Assume that sh is compiled in... */
1688
+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1689
+ return xstrdup_or_null (busybox_path );
1690
+
1691
+ if (!applets .nr ) {
1692
+ struct child_process cp = CHILD_PROCESS_INIT ;
1693
+ struct strbuf buf = STRBUF_INIT ;
1694
+ char * p ;
1695
+
1696
+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1697
+
1698
+ if (capture_command (& cp , & buf , 2048 )) {
1699
+ string_list_append (& applets , "" );
1700
+ return NULL ;
1701
+ }
1702
+
1703
+ /* parse output */
1704
+ p = strstr (buf .buf , "Currently defined functions:\n" );
1705
+ if (!p ) {
1706
+ warning ("Could not parse output of busybox --help" );
1707
+ string_list_append (& applets , "" );
1708
+ return NULL ;
1709
+ }
1710
+ p = strchrnul (p , '\n' );
1711
+ for (;;) {
1712
+ size_t len ;
1713
+
1714
+ p += strspn (p , "\n\t ," );
1715
+ len = strcspn (p , "\n\t ," );
1716
+ if (!len )
1717
+ break ;
1718
+ p [len ] = '\0' ;
1719
+ string_list_insert (& applets , p );
1720
+ p = p + len + 1 ;
1721
+ }
1722
+ }
1723
+
1724
+ return string_list_has_string (& applets , cmd ) ?
1725
+ xstrdup (busybox_path ) : NULL ;
1726
+ }
1727
+
1668
1728
/*
1669
1729
* Determines the absolute path of cmd using the split path in path.
1670
1730
* If cmd contains a slash or backslash, no lookup is performed.
@@ -1693,6 +1753,9 @@ static char *path_lookup(const char *cmd, int exe_only)
1693
1753
path = sep + 1 ;
1694
1754
}
1695
1755
1756
+ if (!prog && !isexe )
1757
+ prog = is_busybox_applet (cmd );
1758
+
1696
1759
return prog ;
1697
1760
}
1698
1761
@@ -1896,8 +1959,8 @@ static int is_msys2_sh(const char *cmd)
1896
1959
}
1897
1960
1898
1961
static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1899
- const char * dir ,
1900
- int prepend_cmd , int fhin , int fhout , int fherr )
1962
+ const char * dir , const char * prepend_cmd ,
1963
+ int fhin , int fhout , int fherr )
1901
1964
{
1902
1965
static int restrict_handle_inheritance = -1 ;
1903
1966
STARTUPINFOEXW si ;
@@ -1988,9 +2051,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
1988
2051
/* concatenate argv, quoting args as we go */
1989
2052
strbuf_init (& args , 0 );
1990
2053
if (prepend_cmd ) {
1991
- char * quoted = (char * )quote_arg (cmd );
2054
+ char * quoted = (char * )quote_arg (prepend_cmd );
1992
2055
strbuf_addstr (& args , quoted );
1993
- if (quoted != cmd )
2056
+ if (quoted != prepend_cmd )
1994
2057
free (quoted );
1995
2058
}
1996
2059
for (; * argv ; argv ++ ) {
@@ -2149,7 +2212,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
2149
2212
return (pid_t )pi .dwProcessId ;
2150
2213
}
2151
2214
2152
- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2215
+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2216
+ const char * prepend_cmd )
2153
2217
{
2154
2218
return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
2155
2219
}
@@ -2177,14 +2241,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
2177
2241
pid = -1 ;
2178
2242
}
2179
2243
else {
2180
- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2244
+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
2181
2245
fhin , fhout , fherr );
2182
2246
free (iprog );
2183
2247
}
2184
2248
argv [0 ] = argv0 ;
2185
2249
}
2186
2250
else
2187
- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2251
+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
2188
2252
fhin , fhout , fherr );
2189
2253
free (prog );
2190
2254
}
@@ -2209,7 +2273,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
2209
2273
argv2 [0 ] = (char * )cmd ; /* full path to the script file */
2210
2274
COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
2211
2275
exec_id = trace2_exec (prog , (const char * * )argv2 );
2212
- pid = mingw_spawnv (prog , (const char * * )argv2 , 1 );
2276
+ pid = mingw_spawnv (prog , (const char * * )argv2 , interpr );
2213
2277
if (pid >= 0 ) {
2214
2278
int status ;
2215
2279
if (waitpid (pid , & status , 0 ) < 0 )
@@ -2233,7 +2297,7 @@ int mingw_execv(const char *cmd, char *const *argv)
2233
2297
int exec_id ;
2234
2298
2235
2299
exec_id = trace2_exec (cmd , (const char * * )argv );
2236
- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2300
+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
2237
2301
if (pid < 0 ) {
2238
2302
trace2_exec_result (exec_id , -1 );
2239
2303
return -1 ;
0 commit comments