1515#include <sspi.h>
1616#include "win32/fscache.h"
1717#include "../attr.h"
18+ #include "../string-list.h"
1819
1920#define HCAST (type , handle ) ((type)(intptr_t)handle)
2021
@@ -1629,6 +1630,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16291630 return NULL ;
16301631}
16311632
1633+ static char * path_lookup (const char * cmd , int exe_only );
1634+
1635+ static char * is_busybox_applet (const char * cmd )
1636+ {
1637+ static struct string_list applets = STRING_LIST_INIT_DUP ;
1638+ static char * busybox_path ;
1639+ static int busybox_path_initialized ;
1640+
1641+ /* Avoid infinite loop */
1642+ if (!strncasecmp (cmd , "busybox" , 7 ) &&
1643+ (!cmd [7 ] || !strcasecmp (cmd + 7 , ".exe" )))
1644+ return NULL ;
1645+
1646+ if (!busybox_path_initialized ) {
1647+ busybox_path = path_lookup ("busybox.exe" , 1 );
1648+ busybox_path_initialized = 1 ;
1649+ }
1650+
1651+ /* Assume that sh is compiled in... */
1652+ if (!busybox_path || !strcasecmp (cmd , "sh" ))
1653+ return xstrdup_or_null (busybox_path );
1654+
1655+ if (!applets .nr ) {
1656+ struct child_process cp = CHILD_PROCESS_INIT ;
1657+ struct strbuf buf = STRBUF_INIT ;
1658+ char * p ;
1659+
1660+ strvec_pushl (& cp .args , busybox_path , "--help" , NULL );
1661+
1662+ if (capture_command (& cp , & buf , 2048 )) {
1663+ string_list_append (& applets , "" );
1664+ return NULL ;
1665+ }
1666+
1667+ /* parse output */
1668+ p = strstr (buf .buf , "Currently defined functions:\n" );
1669+ if (!p ) {
1670+ warning ("Could not parse output of busybox --help" );
1671+ string_list_append (& applets , "" );
1672+ return NULL ;
1673+ }
1674+ p = strchrnul (p , '\n' );
1675+ for (;;) {
1676+ size_t len ;
1677+
1678+ p += strspn (p , "\n\t ," );
1679+ len = strcspn (p , "\n\t ," );
1680+ if (!len )
1681+ break ;
1682+ p [len ] = '\0' ;
1683+ string_list_insert (& applets , p );
1684+ p = p + len + 1 ;
1685+ }
1686+ }
1687+
1688+ return string_list_has_string (& applets , cmd ) ?
1689+ xstrdup (busybox_path ) : NULL ;
1690+ }
1691+
16321692/*
16331693 * Determines the absolute path of cmd using the split path in path.
16341694 * If cmd contains a slash or backslash, no lookup is performed.
@@ -1657,6 +1717,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16571717 path = sep + 1 ;
16581718 }
16591719
1720+ if (!prog && !isexe )
1721+ prog = is_busybox_applet (cmd );
1722+
16601723 return prog ;
16611724}
16621725
@@ -1856,8 +1919,8 @@ static int is_msys2_sh(const char *cmd)
18561919}
18571920
18581921static pid_t mingw_spawnve_fd (const char * cmd , const char * * argv , char * * deltaenv ,
1859- const char * dir ,
1860- int prepend_cmd , int fhin , int fhout , int fherr )
1922+ const char * dir , const char * prepend_cmd ,
1923+ int fhin , int fhout , int fherr )
18611924{
18621925 static int restrict_handle_inheritance = -1 ;
18631926 STARTUPINFOEXW si ;
@@ -1948,9 +2011,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19482011 /* concatenate argv, quoting args as we go */
19492012 strbuf_init (& args , 0 );
19502013 if (prepend_cmd ) {
1951- char * quoted = (char * )quote_arg (cmd );
2014+ char * quoted = (char * )quote_arg (prepend_cmd );
19522015 strbuf_addstr (& args , quoted );
1953- if (quoted != cmd )
2016+ if (quoted != prepend_cmd )
19542017 free (quoted );
19552018 }
19562019 for (; * argv ; argv ++ ) {
@@ -2109,7 +2172,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21092172 return (pid_t )pi .dwProcessId ;
21102173}
21112174
2112- static pid_t mingw_spawnv (const char * cmd , const char * * argv , int prepend_cmd )
2175+ static pid_t mingw_spawnv (const char * cmd , const char * * argv ,
2176+ const char * prepend_cmd )
21132177{
21142178 return mingw_spawnve_fd (cmd , argv , NULL , NULL , prepend_cmd , 0 , 1 , 2 );
21152179}
@@ -2137,14 +2201,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21372201 pid = -1 ;
21382202 }
21392203 else {
2140- pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , 1 ,
2204+ pid = mingw_spawnve_fd (iprog , argv , deltaenv , dir , interpr ,
21412205 fhin , fhout , fherr );
21422206 free (iprog );
21432207 }
21442208 argv [0 ] = argv0 ;
21452209 }
21462210 else
2147- pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , 0 ,
2211+ pid = mingw_spawnve_fd (prog , argv , deltaenv , dir , NULL ,
21482212 fhin , fhout , fherr );
21492213 free (prog );
21502214 }
@@ -2172,7 +2236,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21722236 argv2 [0 ] = (char * )cmd ; /* full path to the script file */
21732237 COPY_ARRAY (& argv2 [1 ], & argv [1 ], argc );
21742238 exec_id = trace2_exec (prog , argv2 );
2175- pid = mingw_spawnv (prog , argv2 , 1 );
2239+ pid = mingw_spawnv (prog , argv2 , interpr );
21762240 if (pid >= 0 ) {
21772241 int status ;
21782242 if (waitpid (pid , & status , 0 ) < 0 )
@@ -2196,7 +2260,7 @@ int mingw_execv(const char *cmd, char *const *argv)
21962260 int exec_id ;
21972261
21982262 exec_id = trace2_exec (cmd , (const char * * )argv );
2199- pid = mingw_spawnv (cmd , (const char * * )argv , 0 );
2263+ pid = mingw_spawnv (cmd , (const char * * )argv , NULL );
22002264 if (pid < 0 ) {
22012265 trace2_exec_result (exec_id , -1 );
22022266 return -1 ;
0 commit comments