aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-05-15 21:21:25 +0100
committerRon Yorston <rmy@pobox.com>2014-05-15 21:21:25 +0100
commit40a4b0c0643ea50582f808ef9a40e854819c9ccd (patch)
treeebcc604cfdbcee28f7758247ada2118f145fa61b
parent1ae26218b9700756ff723a065f011e88f5d3ef81 (diff)
downloadbusybox-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.c106
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
4typedef struct { 4typedef 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
11static pipe_data *pipes = NULL; 11static 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
149finito: 153finito:
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
179int mingw_pclose(FILE *fd) 171int 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