diff options
author | Ron Yorston <rmy@pobox.com> | 2012-05-01 14:38:19 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-05-01 14:38:19 +0100 |
commit | 3aed4dbdecd66769dc0865ee869a920c1db4c988 (patch) | |
tree | 56e9a73d58f25e57998b4a4cf6ab37ef24287e70 | |
parent | aa5bfb88d69ea24c74355298c671e07bce240d83 (diff) | |
download | busybox-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.h | 3 | ||||
-rw-r--r-- | win32/system.c | 77 |
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 | ||
172 | int mingw_system(const char *cmd); | ||
173 | #define system mingw_system | ||
174 | |||
172 | int clearenv(void); | 175 | int clearenv(void); |
173 | char *mingw_getenv(const char *name); | 176 | char *mingw_getenv(const char *name); |
174 | int mkstemp(char *template); | 177 | 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 @@ | |||
1 | #include "libbb.h" | ||
2 | |||
3 | int 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 | } | ||