diff options
author | Ron Yorston <rmy@pobox.com> | 2014-05-15 21:21:25 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-05-15 21:21:25 +0100 |
commit | 40a4b0c0643ea50582f808ef9a40e854819c9ccd (patch) | |
tree | ebcc604cfdbcee28f7758247ada2118f145fa61b | |
parent | 1ae26218b9700756ff723a065f011e88f5d3ef81 (diff) | |
download | busybox-w32-40a4b0c0643ea50582f808ef9a40e854819c9ccd.tar.gz busybox-w32-40a4b0c0643ea50582f808ef9a40e854819c9ccd.tar.bz2 busybox-w32-40a4b0c0643ea50582f808ef9a40e854819c9ccd.zip |
Tidy up mingw_popen
This also fixes piping output to a command in awk.
-rw-r--r-- | win32/popen.c | 106 |
1 files changed, 47 insertions, 59 deletions
diff --git a/win32/popen.c b/win32/popen.c index b75ddbcb6..a7b2c7ec9 100644 --- a/win32/popen.c +++ b/win32/popen.c | |||
@@ -3,9 +3,9 @@ | |||
3 | 3 | ||
4 | typedef struct { | 4 | typedef struct { |
5 | PROCESS_INFORMATION piProcInfo; | 5 | PROCESS_INFORMATION piProcInfo; |
6 | HANDLE in[2], out[2], err[2]; | 6 | HANDLE pipe[2]; |
7 | char mode; | 7 | char mode; |
8 | FILE *fd; | 8 | int fd; |
9 | } pipe_data; | 9 | } pipe_data; |
10 | 10 | ||
11 | static pipe_data *pipes = NULL; | 11 | static pipe_data *pipes = NULL; |
@@ -35,6 +35,7 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
35 | int success; | 35 | int success; |
36 | int fd; | 36 | int fd; |
37 | int len, count; | 37 | int len, count; |
38 | int ip, ic; | ||
38 | char *cmd_buff = NULL; | 39 | char *cmd_buff = NULL; |
39 | const char *s; | 40 | const char *s; |
40 | char *t; | 41 | char *t; |
@@ -90,39 +91,43 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
90 | *t++ = '"'; | 91 | *t++ = '"'; |
91 | *t = '\0'; | 92 | *t = '\0'; |
92 | 93 | ||
93 | p->in[0] = INVALID_HANDLE_VALUE; | 94 | p->pipe[0] = INVALID_HANDLE_VALUE; |
94 | p->in[1] = INVALID_HANDLE_VALUE; | 95 | p->pipe[1] = INVALID_HANDLE_VALUE; |
95 | p->out[0] = INVALID_HANDLE_VALUE; | 96 | |
96 | p->out[1] = INVALID_HANDLE_VALUE; | 97 | /* Create the pipe */ |
97 | p->err[0] = INVALID_HANDLE_VALUE; | 98 | if ( mingw_pipe(p->pipe) == -1 ) { |
98 | p->err[1] = INVALID_HANDLE_VALUE; | ||
99 | |||
100 | /* Create the Pipes... */ | ||
101 | if ( mingw_pipe(p->in) == -1 || | ||
102 | mingw_pipe(p->out) == -1 || | ||
103 | mingw_pipe(p->err) == -1) { | ||
104 | goto finito; | 99 | goto finito; |
105 | } | 100 | } |
106 | 101 | ||
107 | /* Make the parent ends of the pipes non-inheritable */ | 102 | /* index of parent end of pipe */ |
108 | SetHandleInformation(p->in[1], HANDLE_FLAG_INHERIT, 0); | 103 | ip = !(*mode == 'r'); |
109 | SetHandleInformation(p->out[0], HANDLE_FLAG_INHERIT, 0); | 104 | /* index of child end of pipe */ |
110 | SetHandleInformation(p->err[0], HANDLE_FLAG_INHERIT, 0); | 105 | ic = (*mode == 'r'); |
106 | |||
107 | /* Make the parent end of the pipe non-inheritable */ | ||
108 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | ||
111 | 109 | ||
112 | /* Now create the child process */ | 110 | /* Now create the child process */ |
113 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | 111 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); |
114 | siStartInfo.cb = sizeof(STARTUPINFO); | 112 | siStartInfo.cb = sizeof(STARTUPINFO); |
115 | siStartInfo.hStdInput = p->in[0]; | 113 | if ( *mode == 'r' ) { |
116 | siStartInfo.hStdOutput = p->out[1]; | 114 | siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); |
117 | siStartInfo.hStdError = p->err[1]; | 115 | siStartInfo.hStdOutput = p->pipe[ic]; |
118 | siStartInfo.dwFlags = STARTF_USESTDHANDLES; | 116 | } |
117 | else { | ||
118 | siStartInfo.hStdInput = p->pipe[ic]; | ||
119 | siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | ||
120 | } | ||
121 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | ||
122 | siStartInfo.wShowWindow = SW_HIDE; | ||
123 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | ||
119 | 124 | ||
120 | success = CreateProcess(NULL, | 125 | success = CreateProcess(NULL, |
121 | (LPTSTR)cmd_buff, /* command line */ | 126 | (LPTSTR)cmd_buff, /* command line */ |
122 | NULL, /* process security attributes */ | 127 | NULL, /* process security attributes */ |
123 | NULL, /* primary thread security attributes */ | 128 | NULL, /* primary thread security attributes */ |
124 | TRUE, /* handles are inherited */ | 129 | TRUE, /* handles are inherited */ |
125 | CREATE_NO_WINDOW, /* creation flags */ | 130 | 0, /* creation flags */ |
126 | NULL, /* use parent's environment */ | 131 | NULL, /* use parent's environment */ |
127 | NULL, /* use parent's current directory */ | 132 | NULL, /* use parent's current directory */ |
128 | &siStartInfo, /* STARTUPINFO pointer */ | 133 | &siStartInfo, /* STARTUPINFO pointer */ |
@@ -132,63 +137,51 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
132 | goto finito; | 137 | goto finito; |
133 | } | 138 | } |
134 | 139 | ||
135 | /* Close the child ends of the pipes */ | 140 | /* close child end of pipe */ |
136 | CloseHandle(p->in[0]); p->in[0] = INVALID_HANDLE_VALUE; | 141 | CloseHandle(p->pipe[ic]); |
137 | CloseHandle(p->out[1]); p->out[1] = INVALID_HANDLE_VALUE; | 142 | p->pipe[ic] = INVALID_HANDLE_VALUE; |
138 | CloseHandle(p->err[1]); p->err[1] = INVALID_HANDLE_VALUE; | ||
139 | 143 | ||
140 | if ( *mode == 'r' ) { | 144 | if ( *mode == 'r' ) { |
141 | fd = _open_osfhandle((long)p->out[0], _O_RDONLY|_O_BINARY); | 145 | fd = _open_osfhandle((long)p->pipe[ip], _O_RDONLY|_O_BINARY); |
142 | fptr = _fdopen(fd, "rb"); | 146 | fptr = _fdopen(fd, "rb"); |
143 | } | 147 | } |
144 | else { | 148 | else { |
145 | fd = _open_osfhandle((long)p->in[1], _O_WRONLY|_O_BINARY); | 149 | fd = _open_osfhandle((long)p->pipe[ip], _O_WRONLY|_O_BINARY); |
146 | fptr = _fdopen(fd, "wb"); | 150 | fptr = _fdopen(fd, "wb"); |
147 | } | 151 | } |
148 | 152 | ||
149 | finito: | 153 | finito: |
150 | if ( !fptr ) { | 154 | if ( !fptr ) { |
151 | if ( p->in[0] != INVALID_HANDLE_VALUE ) { | 155 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { |
152 | CloseHandle(p->in[0]); | 156 | CloseHandle(p->pipe[0]); |
153 | } | ||
154 | if ( p->in[1] != INVALID_HANDLE_VALUE ) { | ||
155 | CloseHandle(p->in[1]); | ||
156 | } | 157 | } |
157 | if ( p->out[0] != INVALID_HANDLE_VALUE ) { | 158 | if ( p->pipe[1] != INVALID_HANDLE_VALUE ) { |
158 | CloseHandle(p->out[0]); | 159 | CloseHandle(p->pipe[1]); |
159 | } | ||
160 | if ( p->out[1] != INVALID_HANDLE_VALUE ) { | ||
161 | CloseHandle(p->out[1]); | ||
162 | } | ||
163 | if ( p->err[0] != INVALID_HANDLE_VALUE ) { | ||
164 | CloseHandle(p->err[0]); | ||
165 | } | ||
166 | if ( p->err[1] != INVALID_HANDLE_VALUE ) { | ||
167 | CloseHandle(p->err[1]); | ||
168 | } | 160 | } |
169 | } | 161 | } |
170 | else { | 162 | else { |
171 | p->mode = *mode; | 163 | p->mode = *mode; |
164 | p->fd = fd; | ||
172 | } | 165 | } |
173 | free(cmd_buff); | 166 | free(cmd_buff); |
174 | 167 | ||
175 | p->fd = fptr; | ||
176 | return fptr; | 168 | return fptr; |
177 | } | 169 | } |
178 | 170 | ||
179 | int mingw_pclose(FILE *fd) | 171 | int mingw_pclose(FILE *fp) |
180 | { | 172 | { |
181 | int i; | 173 | int i, ip, fd; |
182 | pipe_data *p = NULL; | 174 | pipe_data *p = NULL; |
183 | DWORD ret; | 175 | DWORD ret; |
184 | 176 | ||
185 | if ( fd == NULL ) { | 177 | if ( fp == NULL ) { |
186 | return -1; | 178 | return -1; |
187 | } | 179 | } |
188 | 180 | ||
189 | /* find struct containing fd */ | 181 | /* find struct containing fd */ |
182 | fd = fileno(fp); | ||
190 | for ( i=0; i<num_pipes; ++i ) { | 183 | for ( i=0; i<num_pipes; ++i ) { |
191 | if ( pipes[i].fd == fd ) { | 184 | if ( pipes[i].mode && pipes[i].fd == fd ) { |
192 | p = pipes+i; | 185 | p = pipes+i; |
193 | break; | 186 | break; |
194 | } | 187 | } |
@@ -199,15 +192,10 @@ int mingw_pclose(FILE *fd) | |||
199 | return -1; | 192 | return -1; |
200 | } | 193 | } |
201 | 194 | ||
202 | fclose(fd); | 195 | fclose(fp); |
203 | 196 | ||
204 | CloseHandle(p->err[0]); | 197 | ip = !(p->mode == 'r'); |
205 | if ( p->mode == 'r' ) { | 198 | CloseHandle(p->pipe[ip]); |
206 | CloseHandle(p->in[1]); | ||
207 | } | ||
208 | else { | ||
209 | CloseHandle(p->out[0]); | ||
210 | } | ||
211 | 199 | ||
212 | ret = WaitForSingleObject(p->piProcInfo.hProcess, INFINITE); | 200 | ret = WaitForSingleObject(p->piProcInfo.hProcess, INFINITE); |
213 | 201 | ||