aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-05-01 14:38:19 +0100
committerRon Yorston <rmy@pobox.com>2012-05-01 14:38:19 +0100
commit3aed4dbdecd66769dc0865ee869a920c1db4c988 (patch)
tree56e9a73d58f25e57998b4a4cf6ab37ef24287e70
parentaa5bfb88d69ea24c74355298c671e07bce240d83 (diff)
downloadbusybox-w32-3aed4dbdecd66769dc0865ee869a920c1db4c988.tar.gz
busybox-w32-3aed4dbdecd66769dc0865ee869a920c1db4c988.tar.bz2
busybox-w32-3aed4dbdecd66769dc0865ee869a920c1db4c988.zip
mingw32: implement system(3) call using sh instead of cmd.exe
-rw-r--r--include/mingw.h3
-rw-r--r--win32/system.c77
2 files changed, 80 insertions, 0 deletions
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);
169#define WTERMSIG(x) ((x) & 0x7f) 169#define WTERMSIG(x) ((x) & 0x7f)
170#define WCOREDUMP(x) 0 170#define WCOREDUMP(x) 0
171 171
172int mingw_system(const char *cmd);
173#define system mingw_system
174
172int clearenv(void); 175int clearenv(void);
173char *mingw_getenv(const char *name); 176char *mingw_getenv(const char *name);
174int mkstemp(char *template); 177int 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 @@
1#include "libbb.h"
2
3int mingw_system(const char *cmd)
4{
5 STARTUPINFO siStartInfo;
6 PROCESS_INFORMATION piProcInfo;
7 int success;
8 int len, count;
9 char *cmd_buff = NULL;
10 const char *s;
11 char *t;
12 DWORD ret;
13
14 if ( cmd == NULL ) {
15 return 1;
16 }
17
18 /* count double quotes */
19 count = 0;
20 for ( s=cmd; *s; ++s ) {
21 if ( *s == '"' ) {
22 ++count;
23 }
24 }
25
26 len = strlen(cmd) + 10 + count;
27 if ( (cmd_buff=malloc(len)) == NULL ) {
28 return -1;
29 }
30
31 /* escape double quotes */
32 strcpy(cmd_buff, "sh -c \"");
33 for ( s=cmd,t=cmd_buff+strlen(cmd_buff); *s; ++s ) {
34 if ( *s == '"' ) {
35 *t++ = '\\';
36 }
37 *t++ = *s;
38 }
39 *t++ = '"';
40 *t = '\0';
41
42 /* Now create the child process */
43 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
44 siStartInfo.cb = sizeof(STARTUPINFO);
45 siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
46 siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
47 siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
48 siStartInfo.dwFlags = STARTF_USESTDHANDLES;
49
50 success = CreateProcess(NULL,
51 (LPTSTR)cmd_buff, /* command line */
52 NULL, /* process security attributes */
53 NULL, /* primary thread security attributes */
54 TRUE, /* handles are inherited */
55 0, /* creation flags */
56 NULL, /* use parent's environment */
57 NULL, /* use parent's current directory */
58 &siStartInfo, /* STARTUPINFO pointer */
59 &piProcInfo); /* receives PROCESS_INFORMATION */
60
61 if ( !success ) {
62 free(cmd_buff);
63 return 127;
64 }
65
66 free(cmd_buff);
67
68 WaitForSingleObject(piProcInfo.hProcess, INFINITE);
69
70 ret = 0;
71 GetExitCodeProcess(piProcInfo.hProcess, &ret);
72
73 CloseHandle(piProcInfo.hProcess);
74 CloseHandle(piProcInfo.hThread);
75
76 return WEXITSTATUS(ret);
77}