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