diff options
| author | Ron Yorston <rmy@pobox.com> | 2018-03-15 15:35:24 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2018-03-15 15:35:24 +0000 |
| commit | 701cea96c43d185ebe433df9ecca39ecc9742ef3 (patch) | |
| tree | b9b0dcc699f5319f0055d5d29aded690ff37258b | |
| parent | 7cc082e2370da69c8783812c251190d316ce82b3 (diff) | |
| download | busybox-w32-701cea96c43d185ebe433df9ecca39ecc9742ef3.tar.gz busybox-w32-701cea96c43d185ebe433df9ecca39ecc9742ef3.tar.bz2 busybox-w32-701cea96c43d185ebe433df9ecca39ecc9742ef3.zip | |
win32: tidy up popen implementation
Make mingw_popen_fd sufficiently general that it can be used to
implement the other two popen routines.
mingw_popen now just creates a command line and passes it to
mingw_popen_fd. The one call to mingw_popen2 has been replaced
by a call to mingw_popen_fd.
| -rw-r--r-- | include/mingw.h | 1 | ||||
| -rw-r--r-- | networking/wget.c | 3 | ||||
| -rw-r--r-- | win32/popen.c | 281 |
3 files changed, 76 insertions, 209 deletions
diff --git a/include/mingw.h b/include/mingw.h index e56e8f03d..386540b37 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
| @@ -111,7 +111,6 @@ int mingw_rename(const char*, const char*); | |||
| 111 | 111 | ||
| 112 | FILE *mingw_popen(const char *cmd, const char *mode); | 112 | FILE *mingw_popen(const char *cmd, const char *mode); |
| 113 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); | 113 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); |
| 114 | int mingw_popen2(const char *cmd, pid_t *pid); | ||
| 115 | int mingw_pclose(FILE *fd); | 114 | int mingw_pclose(FILE *fd); |
| 116 | #undef popen | 115 | #undef popen |
| 117 | #undef pclose | 116 | #undef pclose |
diff --git a/networking/wget.c b/networking/wget.c index 776894dca..194bf457a 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
| @@ -768,7 +768,6 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
| 768 | static void spawn_ssl_client(const char *host, int network_fd, int flags) | 768 | static void spawn_ssl_client(const char *host, int network_fd, int flags) |
| 769 | { | 769 | { |
| 770 | int fd1; | 770 | int fd1; |
| 771 | pid_t pid; | ||
| 772 | char *servername, *p, *cmd; | 771 | char *servername, *p, *cmd; |
| 773 | 772 | ||
| 774 | servername = xstrdup(host); | 773 | servername = xstrdup(host); |
| @@ -781,7 +780,7 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
| 781 | (void *)_get_osfhandle(network_fd), servername, | 780 | (void *)_get_osfhandle(network_fd), servername, |
| 782 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); | 781 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); |
| 783 | 782 | ||
| 784 | if ( (fd1=mingw_popen2(cmd, &pid)) == -1 ) { | 783 | if ( (fd1=mingw_popen_fd(cmd, "b", -1, NULL)) == -1 ) { |
| 785 | bb_perror_msg_and_die("can't execute ssl_client"); | 784 | bb_perror_msg_and_die("can't execute ssl_client"); |
| 786 | } | 785 | } |
| 787 | 786 | ||
diff --git a/win32/popen.c b/win32/popen.c index c075e2144..6fc04e169 100644 --- a/win32/popen.c +++ b/win32/popen.c | |||
| @@ -12,19 +12,47 @@ typedef struct { | |||
| 12 | static pipe_data *pipes = NULL; | 12 | static pipe_data *pipes = NULL; |
| 13 | static int num_pipes = 0; | 13 | static int num_pipes = 0; |
| 14 | 14 | ||
| 15 | static int mingw_pipe(HANDLE *readwrite) | 15 | static int mingw_pipe(pipe_data *p, int bidi) |
| 16 | { | 16 | { |
| 17 | int ret = 0; | ||
| 17 | SECURITY_ATTRIBUTES sa; | 18 | SECURITY_ATTRIBUTES sa; |
| 18 | 19 | ||
| 19 | sa.nLength = sizeof(sa); /* Length in bytes */ | 20 | sa.nLength = sizeof(sa); /* Length in bytes */ |
| 20 | sa.bInheritHandle = 1; /* the child must inherit these handles */ | 21 | sa.bInheritHandle = 1; /* the child must inherit these handles */ |
| 21 | sa.lpSecurityDescriptor = NULL; | 22 | sa.lpSecurityDescriptor = NULL; |
| 22 | 23 | ||
| 23 | if ( !CreatePipe (&readwrite[0], &readwrite[1], &sa, 1 << 13) ) { | 24 | if (!bidi) { |
| 24 | return -1; | 25 | /* pipe[0] is the read handle, pipe[i] the write handle */ |
| 26 | if ( !CreatePipe (&p->pipe[0], &p->pipe[1], &sa, 1 << 13) ) { | ||
| 27 | return -1; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | else { | ||
| 31 | char *name; | ||
| 32 | const int ip = 1; /* index of parent end of pipe */ | ||
| 33 | const int ic = 0; /* index of child end of pipe */ | ||
| 34 | |||
| 35 | name = xasprintf("\\\\.\\pipe\\bb_pipe.%d.%d", getpid(), | ||
| 36 | (int)(p-pipes)); | ||
| 37 | |||
| 38 | p->pipe[ip] = CreateNamedPipe(name, | ||
| 39 | PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, | ||
| 40 | PIPE_TYPE_BYTE|PIPE_WAIT, | ||
| 41 | 1, 4096, 4096, 0, &sa); | ||
| 42 | |||
| 43 | p->pipe[ic] = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, &sa, | ||
| 44 | OPEN_EXISTING, | ||
| 45 | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, | ||
| 46 | NULL); | ||
| 47 | if (p->pipe[ip] == INVALID_HANDLE_VALUE || | ||
| 48 | p->pipe[ic] == INVALID_HANDLE_VALUE) { | ||
| 49 | ret = -1; | ||
| 50 | } | ||
| 51 | |||
| 52 | free(name); | ||
| 25 | } | 53 | } |
| 26 | 54 | ||
| 27 | return 0; | 55 | return ret; |
| 28 | } | 56 | } |
| 29 | 57 | ||
| 30 | static pipe_data *find_pipe(void) | 58 | static pipe_data *find_pipe(void) |
| @@ -56,19 +84,16 @@ static pipe_data *find_pipe(void) | |||
| 56 | 84 | ||
| 57 | p->pipe[0] = INVALID_HANDLE_VALUE; | 85 | p->pipe[0] = INVALID_HANDLE_VALUE; |
| 58 | p->pipe[1] = INVALID_HANDLE_VALUE; | 86 | p->pipe[1] = INVALID_HANDLE_VALUE; |
| 87 | p->fd = -1; | ||
| 59 | 88 | ||
| 60 | return p; | 89 | return p; |
| 61 | } | 90 | } |
| 62 | 91 | ||
| 63 | FILE *mingw_popen(const char *cmd, const char *mode) | 92 | FILE *mingw_popen(const char *cmd, const char *mode) |
| 64 | { | 93 | { |
| 65 | pipe_data *p; | ||
| 66 | FILE *fptr = NULL; | 94 | FILE *fptr = NULL; |
| 67 | STARTUPINFO siStartInfo; | ||
| 68 | int success; | ||
| 69 | int fd; | 95 | int fd; |
| 70 | int len, count; | 96 | int len, count; |
| 71 | int ip, ic; | ||
| 72 | char *cmd_buff = NULL; | 97 | char *cmd_buff = NULL; |
| 73 | const char *s; | 98 | const char *s; |
| 74 | char *t; | 99 | char *t; |
| @@ -78,11 +103,6 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
| 78 | return NULL; | 103 | return NULL; |
| 79 | } | 104 | } |
| 80 | 105 | ||
| 81 | /* find an unused pipe structure */ | ||
| 82 | if ( (p=find_pipe()) == NULL ) { | ||
| 83 | return NULL; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* count double quotes */ | 106 | /* count double quotes */ |
| 87 | count = 0; | 107 | count = 0; |
| 88 | for ( s=cmd; *s; ++s ) { | 108 | for ( s=cmd; *s; ++s ) { |
| @@ -117,84 +137,25 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
| 117 | *t = '\0'; | 137 | *t = '\0'; |
| 118 | 138 | ||
| 119 | /* Create the pipe */ | 139 | /* Create the pipe */ |
| 120 | if ( mingw_pipe(p->pipe) == -1 ) { | 140 | if ((fd=mingw_popen_fd(cmd_buff, mode, -1, NULL)) != -1) { |
| 121 | goto finito; | 141 | fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); |
| 122 | } | ||
| 123 | |||
| 124 | /* index of parent end of pipe */ | ||
| 125 | ip = !(*mode == 'r'); | ||
| 126 | /* index of child end of pipe */ | ||
| 127 | ic = (*mode == 'r'); | ||
| 128 | |||
| 129 | /* Make the parent end of the pipe non-inheritable */ | ||
| 130 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | ||
| 131 | |||
| 132 | /* Now create the child process */ | ||
| 133 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
| 134 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
| 135 | if ( *mode == 'r' ) { | ||
| 136 | siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | ||
| 137 | siStartInfo.hStdOutput = p->pipe[ic]; | ||
| 138 | } | 142 | } |
| 139 | else { | ||
| 140 | siStartInfo.hStdInput = p->pipe[ic]; | ||
| 141 | siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 142 | } | ||
| 143 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | ||
| 144 | siStartInfo.wShowWindow = SW_HIDE; | ||
| 145 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | ||
| 146 | |||
| 147 | success = CreateProcess(NULL, | ||
| 148 | (LPTSTR)cmd_buff, /* command line */ | ||
| 149 | NULL, /* process security attributes */ | ||
| 150 | NULL, /* primary thread security attributes */ | ||
| 151 | TRUE, /* handles are inherited */ | ||
| 152 | 0, /* creation flags */ | ||
| 153 | NULL, /* use parent's environment */ | ||
| 154 | NULL, /* use parent's current directory */ | ||
| 155 | &siStartInfo, /* STARTUPINFO pointer */ | ||
| 156 | &p->piProcInfo); /* receives PROCESS_INFORMATION */ | ||
| 157 | 143 | ||
| 158 | if ( !success ) { | ||
| 159 | goto finito; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* close child end of pipe */ | ||
| 163 | CloseHandle(p->pipe[ic]); | ||
| 164 | p->pipe[ic] = INVALID_HANDLE_VALUE; | ||
| 165 | |||
| 166 | if ( *mode == 'r' ) { | ||
| 167 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_RDONLY|_O_BINARY); | ||
| 168 | fptr = _fdopen(fd, "rb"); | ||
| 169 | } | ||
| 170 | else { | ||
| 171 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_WRONLY|_O_BINARY); | ||
| 172 | fptr = _fdopen(fd, "wb"); | ||
| 173 | } | ||
| 174 | |||
| 175 | finito: | ||
| 176 | if ( !fptr ) { | ||
| 177 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { | ||
| 178 | CloseHandle(p->pipe[0]); | ||
| 179 | } | ||
| 180 | if ( p->pipe[1] != INVALID_HANDLE_VALUE ) { | ||
| 181 | CloseHandle(p->pipe[1]); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | else { | ||
| 185 | p->mode = *mode; | ||
| 186 | p->fd = fd; | ||
| 187 | } | ||
| 188 | free(cmd_buff); | 144 | free(cmd_buff); |
| 189 | 145 | ||
| 190 | return fptr; | 146 | return fptr; |
| 191 | } | 147 | } |
| 192 | 148 | ||
| 193 | /* | 149 | /* |
| 194 | * Open a pipe to a command where the file descriptor fd0 is used | 150 | * Open a pipe to a command. |
| 195 | * as input to the command (read mode) or as the destination of the | 151 | * |
| 196 | * output from the command (write mode). The pid of the command is | 152 | * - mode may be "r", "w" or "b" for read-only, write-only or |
| 197 | * returned in the variable pid, which can be NULL. | 153 | * bidirectional (from the perspective of the parent). |
| 154 | * - if fd0 is a valid file descriptor it's used as input to the | ||
| 155 | * command ("r") or as the destination of the output from the | ||
| 156 | * command ("w"). Otherwise (and if not "b") use stdin or stdout. | ||
| 157 | * - the pid of the command is returned in the variable pid, which | ||
| 158 | * can be NULL if the pid is not required. | ||
| 198 | */ | 159 | */ |
| 199 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) | 160 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) |
| 200 | { | 161 | { |
| @@ -202,110 +163,29 @@ int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) | |||
| 202 | STARTUPINFO siStartInfo; | 163 | STARTUPINFO siStartInfo; |
| 203 | int success; | 164 | int success; |
| 204 | int fd = -1; | 165 | int fd = -1; |
| 205 | int ip, ic; | 166 | int ip, ic, flags; |
| 206 | 167 | ||
| 207 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || | 168 | if ( cmd == NULL || *cmd == '\0' || mode == NULL ) { |
| 208 | (*mode != 'r' && *mode != 'w') ) { | ||
| 209 | return -1; | 169 | return -1; |
| 210 | } | 170 | } |
| 211 | 171 | ||
| 212 | /* find an unused pipe structure */ | 172 | switch (*mode) { |
| 213 | if ( (p=find_pipe()) == NULL ) { | 173 | case 'r': |
| 214 | return -1; | 174 | ip = 0; |
| 215 | } | 175 | flags = _O_RDONLY|_O_BINARY; |
| 216 | 176 | break; | |
| 217 | /* Create the pipe */ | 177 | case 'w': |
| 218 | if ( mingw_pipe(p->pipe) == -1 ) { | 178 | ip = 1; |
| 219 | goto finito; | 179 | flags = _O_WRONLY|_O_BINARY; |
| 220 | } | 180 | break; |
| 221 | 181 | case 'b': | |
| 222 | /* index of parent end of pipe */ | 182 | ip = 1; |
| 223 | ip = !(*mode == 'r'); | 183 | flags = _O_RDWR|_O_BINARY; |
| 224 | /* index of child end of pipe */ | 184 | break; |
| 225 | ic = (*mode == 'r'); | 185 | default: |
| 226 | |||
| 227 | /* Make the parent end of the pipe non-inheritable */ | ||
| 228 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | ||
| 229 | |||
| 230 | /* Now create the child process */ | ||
| 231 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
| 232 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
| 233 | if ( *mode == 'r' ) { | ||
| 234 | siStartInfo.hStdInput = (HANDLE)_get_osfhandle(fd0); | ||
| 235 | siStartInfo.hStdOutput = p->pipe[ic]; | ||
| 236 | } | ||
| 237 | else { | ||
| 238 | siStartInfo.hStdInput = p->pipe[ic]; | ||
| 239 | siStartInfo.hStdOutput = (HANDLE)_get_osfhandle(fd0); | ||
| 240 | } | ||
| 241 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | ||
| 242 | siStartInfo.wShowWindow = SW_HIDE; | ||
| 243 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | ||
| 244 | |||
| 245 | success = CreateProcess(NULL, | ||
| 246 | (LPTSTR)cmd, /* command line */ | ||
| 247 | NULL, /* process security attributes */ | ||
| 248 | NULL, /* primary thread security attributes */ | ||
| 249 | TRUE, /* handles are inherited */ | ||
| 250 | 0, /* creation flags */ | ||
| 251 | NULL, /* use parent's environment */ | ||
| 252 | NULL, /* use parent's current directory */ | ||
| 253 | &siStartInfo, /* STARTUPINFO pointer */ | ||
| 254 | &p->piProcInfo); /* receives PROCESS_INFORMATION */ | ||
| 255 | |||
| 256 | if ( !success ) { | ||
| 257 | goto finito; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* close child end of pipe */ | ||
| 261 | CloseHandle(p->pipe[ic]); | ||
| 262 | p->pipe[ic] = INVALID_HANDLE_VALUE; | ||
| 263 | |||
| 264 | if ( *mode == 'r' ) { | ||
| 265 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_RDONLY|_O_BINARY); | ||
| 266 | } | ||
| 267 | else { | ||
| 268 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_WRONLY|_O_BINARY); | ||
| 269 | } | ||
| 270 | |||
| 271 | finito: | ||
| 272 | if ( fd == -1 ) { | ||
| 273 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { | ||
| 274 | CloseHandle(p->pipe[0]); | ||
| 275 | } | ||
| 276 | if ( p->pipe[1] != INVALID_HANDLE_VALUE ) { | ||
| 277 | CloseHandle(p->pipe[1]); | ||
| 278 | } | ||
| 279 | } | ||
| 280 | else { | ||
| 281 | p->mode = *mode; | ||
| 282 | p->fd = fd; | ||
| 283 | if ( pid ) { | ||
| 284 | *pid = (pid_t)p->piProcInfo.dwProcessId; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 288 | return fd; | ||
| 289 | } | ||
| 290 | |||
| 291 | /* | ||
| 292 | * Open a bidirectional pipe to a command. The pid of the command is | ||
| 293 | * returned in the variable pid, which can be NULL. | ||
| 294 | */ | ||
| 295 | int mingw_popen2(const char *cmd, pid_t *pid) | ||
| 296 | { | ||
| 297 | pipe_data *p; | ||
| 298 | char *name = NULL; | ||
| 299 | SECURITY_ATTRIBUTES sa; | ||
| 300 | STARTUPINFO siStartInfo; | ||
| 301 | int success; | ||
| 302 | int fd = -1; | ||
| 303 | const int ip = 1; /* index of parent end of pipe */ | ||
| 304 | const int ic = 0; /* index of child end of pipe */ | ||
| 305 | |||
| 306 | if ( cmd == NULL || *cmd == '\0' ) { | ||
| 307 | return -1; | 186 | return -1; |
| 308 | } | 187 | } |
| 188 | ic = !ip; | ||
| 309 | 189 | ||
| 310 | /* find an unused pipe structure */ | 190 | /* find an unused pipe structure */ |
| 311 | if ( (p=find_pipe()) == NULL ) { | 191 | if ( (p=find_pipe()) == NULL ) { |
| @@ -313,26 +193,7 @@ int mingw_popen2(const char *cmd, pid_t *pid) | |||
| 313 | } | 193 | } |
| 314 | 194 | ||
| 315 | /* Create the pipe */ | 195 | /* Create the pipe */ |
| 316 | name = xasprintf("\\\\.\\pipe\\bb_pipe.%d.%d", getpid(), (int)(p-pipes)); | 196 | if ( mingw_pipe(p, *mode == 'b') == -1 ) { |
| 317 | |||
| 318 | sa.nLength = sizeof(sa); /* Length in bytes */ | ||
| 319 | sa.bInheritHandle = 1; /* the child must inherit these handles */ | ||
| 320 | sa.lpSecurityDescriptor = NULL; | ||
| 321 | |||
| 322 | p->pipe[ip] = CreateNamedPipe(name, | ||
| 323 | PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, | ||
| 324 | PIPE_TYPE_BYTE|PIPE_WAIT, | ||
| 325 | 1, 4096, 4096, 0, &sa); | ||
| 326 | if (p->pipe[ip] == INVALID_HANDLE_VALUE) { | ||
| 327 | goto finito; | ||
| 328 | } | ||
| 329 | |||
| 330 | /* Connect to the pipe */ | ||
| 331 | p->pipe[ic] = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, &sa, | ||
| 332 | OPEN_EXISTING, | ||
| 333 | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, | ||
| 334 | NULL); | ||
| 335 | if (p->pipe[ic] == INVALID_HANDLE_VALUE) { | ||
| 336 | goto finito; | 197 | goto finito; |
| 337 | } | 198 | } |
| 338 | 199 | ||
| @@ -342,10 +203,20 @@ int mingw_popen2(const char *cmd, pid_t *pid) | |||
| 342 | /* Now create the child process */ | 203 | /* Now create the child process */ |
| 343 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | 204 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); |
| 344 | siStartInfo.cb = sizeof(STARTUPINFO); | 205 | siStartInfo.cb = sizeof(STARTUPINFO); |
| 345 | siStartInfo.wShowWindow = SW_HIDE; | 206 | /* default settings for a bidirectional pipe */ |
| 346 | siStartInfo.hStdInput = p->pipe[ic]; | 207 | siStartInfo.hStdInput = p->pipe[ic]; |
| 347 | siStartInfo.hStdOutput = p->pipe[ic]; | 208 | siStartInfo.hStdOutput = p->pipe[ic]; |
| 209 | /* override for read-only or write-only */ | ||
| 210 | if ( *mode == 'r' ) { | ||
| 211 | siStartInfo.hStdInput = fd0 >= 0 ? (HANDLE)_get_osfhandle(fd0) : | ||
| 212 | GetStdHandle(STD_INPUT_HANDLE); | ||
| 213 | } | ||
| 214 | else if ( *mode == 'w' ) { | ||
| 215 | siStartInfo.hStdOutput = fd0 >= 0 ? (HANDLE)_get_osfhandle(fd0) : | ||
| 216 | GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 217 | } | ||
| 348 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 218 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); |
| 219 | siStartInfo.wShowWindow = SW_HIDE; | ||
| 349 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | 220 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; |
| 350 | 221 | ||
| 351 | success = CreateProcess(NULL, | 222 | success = CreateProcess(NULL, |
| @@ -367,12 +238,10 @@ int mingw_popen2(const char *cmd, pid_t *pid) | |||
| 367 | CloseHandle(p->pipe[ic]); | 238 | CloseHandle(p->pipe[ic]); |
| 368 | p->pipe[ic] = INVALID_HANDLE_VALUE; | 239 | p->pipe[ic] = INVALID_HANDLE_VALUE; |
| 369 | 240 | ||
| 370 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_RDWR|_O_BINARY); | 241 | fd = _open_osfhandle((intptr_t)p->pipe[ip], flags); |
| 371 | 242 | ||
| 372 | finito: | 243 | finito: |
| 373 | free(name); | ||
| 374 | if ( fd == -1 ) { | 244 | if ( fd == -1 ) { |
| 375 | errno = err_win_to_posix(GetLastError()); | ||
| 376 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { | 245 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { |
| 377 | CloseHandle(p->pipe[0]); | 246 | CloseHandle(p->pipe[0]); |
| 378 | } | 247 | } |
| @@ -381,7 +250,7 @@ finito: | |||
| 381 | } | 250 | } |
| 382 | } | 251 | } |
| 383 | else { | 252 | else { |
| 384 | p->mode = 'r'; | 253 | p->mode = *mode; |
| 385 | p->fd = fd; | 254 | p->fd = fd; |
| 386 | if ( pid ) { | 255 | if ( pid ) { |
| 387 | *pid = (pid_t)p->piProcInfo.dwProcessId; | 256 | *pid = (pid_t)p->piProcInfo.dwProcessId; |
