diff options
author | Ron Yorston <rmy@pobox.com> | 2015-05-27 15:14:20 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-05-27 15:14:20 +0100 |
commit | 8a61b67d502ed4fbd5f480ca9458884b55ce7a95 (patch) | |
tree | 1767659baed55dfb23dd9ca1ac1a7582f9b7087b | |
parent | 42c4505e1e5eb96314176e7b7c1b28adcce22310 (diff) | |
download | busybox-w32-8a61b67d502ed4fbd5f480ca9458884b55ce7a95.tar.gz busybox-w32-8a61b67d502ed4fbd5f480ca9458884b55ce7a95.tar.bz2 busybox-w32-8a61b67d502ed4fbd5f480ca9458884b55ce7a95.zip |
mingw: add routine to pipe a file descriptor to/from a command
-rw-r--r-- | include/mingw.h | 1 | ||||
-rw-r--r-- | win32/popen.c | 146 |
2 files changed, 129 insertions, 18 deletions
diff --git a/include/mingw.h b/include/mingw.h index d6ed909b5..bf8cd0c4c 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -142,6 +142,7 @@ int mingw_rename(const char*, const char*); | |||
142 | #define rename mingw_rename | 142 | #define rename mingw_rename |
143 | 143 | ||
144 | FILE *mingw_popen(const char *cmd, const char *mode); | 144 | FILE *mingw_popen(const char *cmd, const char *mode); |
145 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); | ||
145 | int mingw_pclose(FILE *fd); | 146 | int mingw_pclose(FILE *fd); |
146 | #undef popen | 147 | #undef popen |
147 | #undef pclose | 148 | #undef pclose |
diff --git a/win32/popen.c b/win32/popen.c index a7b2c7ec9..93d51bb55 100644 --- a/win32/popen.c +++ b/win32/popen.c | |||
@@ -26,24 +26,10 @@ static int mingw_pipe(HANDLE *readwrite) | |||
26 | return 0; | 26 | return 0; |
27 | } | 27 | } |
28 | 28 | ||
29 | FILE *mingw_popen(const char *cmd, const char *mode) | 29 | static pipe_data *find_pipe(void) |
30 | { | 30 | { |
31 | int i; | 31 | int i; |
32 | pipe_data *p = NULL; | 32 | pipe_data *p = NULL; |
33 | FILE *fptr = NULL; | ||
34 | STARTUPINFO siStartInfo; | ||
35 | int success; | ||
36 | int fd; | ||
37 | int len, count; | ||
38 | int ip, ic; | ||
39 | char *cmd_buff = NULL; | ||
40 | const char *s; | ||
41 | char *t; | ||
42 | |||
43 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || | ||
44 | (*mode != 'r' && *mode != 'w') ) { | ||
45 | return NULL; | ||
46 | } | ||
47 | 33 | ||
48 | /* find an unused pipe structure */ | 34 | /* find an unused pipe structure */ |
49 | for ( i=0; i<num_pipes; ++i ) { | 35 | for ( i=0; i<num_pipes; ++i ) { |
@@ -67,6 +53,35 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
67 | num_pipes += 10; | 53 | num_pipes += 10; |
68 | } | 54 | } |
69 | 55 | ||
56 | p->pipe[0] = INVALID_HANDLE_VALUE; | ||
57 | p->pipe[1] = INVALID_HANDLE_VALUE; | ||
58 | |||
59 | return p; | ||
60 | } | ||
61 | |||
62 | FILE *mingw_popen(const char *cmd, const char *mode) | ||
63 | { | ||
64 | pipe_data *p; | ||
65 | FILE *fptr = NULL; | ||
66 | STARTUPINFO siStartInfo; | ||
67 | int success; | ||
68 | int fd; | ||
69 | int len, count; | ||
70 | int ip, ic; | ||
71 | char *cmd_buff = NULL; | ||
72 | const char *s; | ||
73 | char *t; | ||
74 | |||
75 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || | ||
76 | (*mode != 'r' && *mode != 'w') ) { | ||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | /* find an unused pipe structure */ | ||
81 | if ( (p=find_pipe()) == NULL ) { | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
70 | /* count double quotes */ | 85 | /* count double quotes */ |
71 | count = 0; | 86 | count = 0; |
72 | for ( s=cmd; *s; ++s ) { | 87 | for ( s=cmd; *s; ++s ) { |
@@ -91,9 +106,6 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
91 | *t++ = '"'; | 106 | *t++ = '"'; |
92 | *t = '\0'; | 107 | *t = '\0'; |
93 | 108 | ||
94 | p->pipe[0] = INVALID_HANDLE_VALUE; | ||
95 | p->pipe[1] = INVALID_HANDLE_VALUE; | ||
96 | |||
97 | /* Create the pipe */ | 109 | /* Create the pipe */ |
98 | if ( mingw_pipe(p->pipe) == -1 ) { | 110 | if ( mingw_pipe(p->pipe) == -1 ) { |
99 | goto finito; | 111 | goto finito; |
@@ -168,6 +180,104 @@ finito: | |||
168 | return fptr; | 180 | return fptr; |
169 | } | 181 | } |
170 | 182 | ||
183 | /* | ||
184 | * Open a pipe to a command where the file descriptor fd0 is used | ||
185 | * as input to the command (read mode) or as the destination of the | ||
186 | * output from the command (write mode). The pid of the command is | ||
187 | * returned in the variable pid, which can be NULL. | ||
188 | */ | ||
189 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) | ||
190 | { | ||
191 | pipe_data *p; | ||
192 | STARTUPINFO siStartInfo; | ||
193 | int success; | ||
194 | int fd = -1; | ||
195 | int ip, ic; | ||
196 | |||
197 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || | ||
198 | (*mode != 'r' && *mode != 'w') ) { | ||
199 | return -1; | ||
200 | } | ||
201 | |||
202 | /* find an unused pipe structure */ | ||
203 | if ( (p=find_pipe()) == NULL ) { | ||
204 | return -1; | ||
205 | } | ||
206 | |||
207 | /* Create the pipe */ | ||
208 | if ( mingw_pipe(p->pipe) == -1 ) { | ||
209 | goto finito; | ||
210 | } | ||
211 | |||
212 | /* index of parent end of pipe */ | ||
213 | ip = !(*mode == 'r'); | ||
214 | /* index of child end of pipe */ | ||
215 | ic = (*mode == 'r'); | ||
216 | |||
217 | /* Make the parent end of the pipe non-inheritable */ | ||
218 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | ||
219 | |||
220 | /* Now create the child process */ | ||
221 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
222 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
223 | if ( *mode == 'r' ) { | ||
224 | siStartInfo.hStdInput = (HANDLE)_get_osfhandle(fd0); | ||
225 | siStartInfo.hStdOutput = p->pipe[ic]; | ||
226 | } | ||
227 | else { | ||
228 | siStartInfo.hStdInput = p->pipe[ic]; | ||
229 | siStartInfo.hStdOutput = (HANDLE)_get_osfhandle(fd0); | ||
230 | } | ||
231 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | ||
232 | siStartInfo.wShowWindow = SW_HIDE; | ||
233 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | ||
234 | |||
235 | success = CreateProcess(NULL, | ||
236 | (LPTSTR)cmd, /* command line */ | ||
237 | NULL, /* process security attributes */ | ||
238 | NULL, /* primary thread security attributes */ | ||
239 | TRUE, /* handles are inherited */ | ||
240 | 0, /* creation flags */ | ||
241 | NULL, /* use parent's environment */ | ||
242 | NULL, /* use parent's current directory */ | ||
243 | &siStartInfo, /* STARTUPINFO pointer */ | ||
244 | &p->piProcInfo); /* receives PROCESS_INFORMATION */ | ||
245 | |||
246 | if ( !success ) { | ||
247 | goto finito; | ||
248 | } | ||
249 | |||
250 | /* close child end of pipe */ | ||
251 | CloseHandle(p->pipe[ic]); | ||
252 | p->pipe[ic] = INVALID_HANDLE_VALUE; | ||
253 | |||
254 | if ( *mode == 'r' ) { | ||
255 | fd = _open_osfhandle((long)p->pipe[ip], _O_RDONLY|_O_BINARY); | ||
256 | } | ||
257 | else { | ||
258 | fd = _open_osfhandle((long)p->pipe[ip], _O_WRONLY|_O_BINARY); | ||
259 | } | ||
260 | |||
261 | finito: | ||
262 | if ( fd == -1 ) { | ||
263 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { | ||
264 | CloseHandle(p->pipe[0]); | ||
265 | } | ||
266 | if ( p->pipe[1] != INVALID_HANDLE_VALUE ) { | ||
267 | CloseHandle(p->pipe[1]); | ||
268 | } | ||
269 | } | ||
270 | else { | ||
271 | p->mode = *mode; | ||
272 | p->fd = fd; | ||
273 | if ( pid ) { | ||
274 | *pid = (pid_t)p->piProcInfo.dwProcessId; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | return fd; | ||
279 | } | ||
280 | |||
171 | int mingw_pclose(FILE *fp) | 281 | int mingw_pclose(FILE *fp) |
172 | { | 282 | { |
173 | int i, ip, fd; | 283 | int i, ip, fd; |