From 3aed4dbdecd66769dc0865ee869a920c1db4c988 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 1 May 2012 14:38:19 +0100 Subject: mingw32: implement system(3) call using sh instead of cmd.exe --- include/mingw.h | 3 +++ win32/system.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 win32/system.c diff --git a/include/mingw.h b/include/mingw.h index a9b14a9b2..08d776c84 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -169,6 +169,9 @@ int winansi_get_terminal_width_height(struct winsize *win); #define WTERMSIG(x) ((x) & 0x7f) #define WCOREDUMP(x) 0 +int mingw_system(const char *cmd); +#define system mingw_system + int clearenv(void); char *mingw_getenv(const char *name); int mkstemp(char *template); diff --git a/win32/system.c b/win32/system.c new file mode 100644 index 000000000..5a56173ec --- /dev/null +++ b/win32/system.c @@ -0,0 +1,77 @@ +#include "libbb.h" + +int mingw_system(const char *cmd) +{ + STARTUPINFO siStartInfo; + PROCESS_INFORMATION piProcInfo; + int success; + int len, count; + char *cmd_buff = NULL; + const char *s; + char *t; + DWORD ret; + + if ( cmd == NULL ) { + return 1; + } + + /* count double quotes */ + count = 0; + for ( s=cmd; *s; ++s ) { + if ( *s == '"' ) { + ++count; + } + } + + len = strlen(cmd) + 10 + count; + if ( (cmd_buff=malloc(len)) == NULL ) { + return -1; + } + + /* escape double quotes */ + strcpy(cmd_buff, "sh -c \""); + for ( s=cmd,t=cmd_buff+strlen(cmd_buff); *s; ++s ) { + if ( *s == '"' ) { + *t++ = '\\'; + } + *t++ = *s; + } + *t++ = '"'; + *t = '\0'; + + /* Now create the child process */ + ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); + siStartInfo.dwFlags = STARTF_USESTDHANDLES; + + success = CreateProcess(NULL, + (LPTSTR)cmd_buff, /* command line */ + NULL, /* process security attributes */ + NULL, /* primary thread security attributes */ + TRUE, /* handles are inherited */ + 0, /* creation flags */ + NULL, /* use parent's environment */ + NULL, /* use parent's current directory */ + &siStartInfo, /* STARTUPINFO pointer */ + &piProcInfo); /* receives PROCESS_INFORMATION */ + + if ( !success ) { + free(cmd_buff); + return 127; + } + + free(cmd_buff); + + WaitForSingleObject(piProcInfo.hProcess, INFINITE); + + ret = 0; + GetExitCodeProcess(piProcInfo.hProcess, &ret); + + CloseHandle(piProcInfo.hProcess); + CloseHandle(piProcInfo.hThread); + + return WEXITSTATUS(ret); +} -- cgit v1.2.3-55-g6feb