aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-05-27 15:14:20 +0100
committerRon Yorston <rmy@pobox.com>2015-05-27 15:14:20 +0100
commit8a61b67d502ed4fbd5f480ca9458884b55ce7a95 (patch)
tree1767659baed55dfb23dd9ca1ac1a7582f9b7087b
parent42c4505e1e5eb96314176e7b7c1b28adcce22310 (diff)
downloadbusybox-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.h1
-rw-r--r--win32/popen.c146
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
144FILE *mingw_popen(const char *cmd, const char *mode); 144FILE *mingw_popen(const char *cmd, const char *mode);
145int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid);
145int mingw_pclose(FILE *fd); 146int 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
29FILE *mingw_popen(const char *cmd, const char *mode) 29static 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
62FILE *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 */
189int 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
261finito:
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
171int mingw_pclose(FILE *fp) 281int mingw_pclose(FILE *fp)
172{ 282{
173 int i, ip, fd; 283 int i, ip, fd;