diff options
author | Ron Yorston <rmy@pobox.com> | 2018-03-15 10:32:23 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-03-15 10:39:20 +0000 |
commit | 7cc082e2370da69c8783812c251190d316ce82b3 (patch) | |
tree | 8a6224f8dd28fb1ffd3e6ef111efcc8b82f429b8 | |
parent | f011d7284d8cabe5d453b43d4df44d0423db22c8 (diff) | |
download | busybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.tar.gz busybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.tar.bz2 busybox-w32-7cc082e2370da69c8783812c251190d316ce82b3.zip |
wget: add support for https
Allow wget to support https URLs. Changes are:
- Add mingw_popen2 which uses a named pipe to allow bidirectional
communication with a child process;
- Modify ssl_client to accept a WIN32 handle instead of a file
descriptor as an argument;
- Allow tls_get_random to open /dev/urandom;
- Using the above changes implement a WIN32 version of spawn_ssl_client
in wget.
This closes GitHub issue #75.
Also, enable authentication in wget.
-rw-r--r-- | configs/mingw32_defconfig | 11 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 11 | ||||
-rw-r--r-- | include/mingw.h | 1 | ||||
-rw-r--r-- | networking/ssl_client.c | 23 | ||||
-rw-r--r-- | networking/tls.c | 6 | ||||
-rw-r--r-- | networking/wget.c | 27 | ||||
-rw-r--r-- | win32/popen.c | 103 |
7 files changed, 171 insertions, 11 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index c143d9f0c..8128764a8 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.29.0.git | 3 | # Busybox version: 1.29.0.git |
4 | # Wed Feb 7 15:11:44 2018 | 4 | # Thu Mar 15 10:05:34 2018 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -478,6 +478,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y | |||
478 | # CONFIG_HALT is not set | 478 | # CONFIG_HALT is not set |
479 | # CONFIG_POWEROFF is not set | 479 | # CONFIG_POWEROFF is not set |
480 | # CONFIG_REBOOT is not set | 480 | # CONFIG_REBOOT is not set |
481 | # CONFIG_FEATURE_WAIT_FOR_INIT is not set | ||
481 | # CONFIG_FEATURE_CALL_TELINIT is not set | 482 | # CONFIG_FEATURE_CALL_TELINIT is not set |
482 | CONFIG_TELINIT_PATH="" | 483 | CONFIG_TELINIT_PATH="" |
483 | # CONFIG_INIT is not set | 484 | # CONFIG_INIT is not set |
@@ -904,7 +905,7 @@ CONFIG_NC_SERVER=y | |||
904 | # CONFIG_PSCAN is not set | 905 | # CONFIG_PSCAN is not set |
905 | # CONFIG_ROUTE is not set | 906 | # CONFIG_ROUTE is not set |
906 | # CONFIG_SLATTACH is not set | 907 | # CONFIG_SLATTACH is not set |
907 | # CONFIG_SSL_CLIENT is not set | 908 | CONFIG_SSL_CLIENT=y |
908 | # CONFIG_TC is not set | 909 | # CONFIG_TC is not set |
909 | # CONFIG_FEATURE_TC_INGRESS is not set | 910 | # CONFIG_FEATURE_TC_INGRESS is not set |
910 | # CONFIG_TCPSVD is not set | 911 | # CONFIG_TCPSVD is not set |
@@ -923,7 +924,7 @@ CONFIG_NC_SERVER=y | |||
923 | # CONFIG_FEATURE_TFTP_PUT is not set | 924 | # CONFIG_FEATURE_TFTP_PUT is not set |
924 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set | 925 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set |
925 | # CONFIG_TFTP_DEBUG is not set | 926 | # CONFIG_TFTP_DEBUG is not set |
926 | # CONFIG_TLS is not set | 927 | CONFIG_TLS=y |
927 | # CONFIG_TRACEROUTE is not set | 928 | # CONFIG_TRACEROUTE is not set |
928 | # CONFIG_TRACEROUTE6 is not set | 929 | # CONFIG_TRACEROUTE6 is not set |
929 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set | 930 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set |
@@ -934,9 +935,9 @@ CONFIG_NC_SERVER=y | |||
934 | CONFIG_WGET=y | 935 | CONFIG_WGET=y |
935 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y | 936 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y |
936 | # CONFIG_FEATURE_WGET_STATUSBAR is not set | 937 | # CONFIG_FEATURE_WGET_STATUSBAR is not set |
937 | # CONFIG_FEATURE_WGET_AUTHENTICATION is not set | 938 | CONFIG_FEATURE_WGET_AUTHENTICATION=y |
938 | # CONFIG_FEATURE_WGET_TIMEOUT is not set | 939 | # CONFIG_FEATURE_WGET_TIMEOUT is not set |
939 | # CONFIG_FEATURE_WGET_HTTPS is not set | 940 | CONFIG_FEATURE_WGET_HTTPS=y |
940 | # CONFIG_FEATURE_WGET_OPENSSL is not set | 941 | # CONFIG_FEATURE_WGET_OPENSSL is not set |
941 | CONFIG_WHOIS=y | 942 | CONFIG_WHOIS=y |
942 | # CONFIG_ZCIP is not set | 943 | # CONFIG_ZCIP is not set |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index 9427f7b5b..d96dc4540 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.29.0.git | 3 | # Busybox version: 1.29.0.git |
4 | # Wed Feb 7 15:18:49 2018 | 4 | # Thu Mar 15 10:21:09 2018 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -478,6 +478,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y | |||
478 | # CONFIG_HALT is not set | 478 | # CONFIG_HALT is not set |
479 | # CONFIG_POWEROFF is not set | 479 | # CONFIG_POWEROFF is not set |
480 | # CONFIG_REBOOT is not set | 480 | # CONFIG_REBOOT is not set |
481 | # CONFIG_FEATURE_WAIT_FOR_INIT is not set | ||
481 | # CONFIG_FEATURE_CALL_TELINIT is not set | 482 | # CONFIG_FEATURE_CALL_TELINIT is not set |
482 | CONFIG_TELINIT_PATH="" | 483 | CONFIG_TELINIT_PATH="" |
483 | # CONFIG_INIT is not set | 484 | # CONFIG_INIT is not set |
@@ -904,7 +905,7 @@ CONFIG_NC_SERVER=y | |||
904 | # CONFIG_PSCAN is not set | 905 | # CONFIG_PSCAN is not set |
905 | # CONFIG_ROUTE is not set | 906 | # CONFIG_ROUTE is not set |
906 | # CONFIG_SLATTACH is not set | 907 | # CONFIG_SLATTACH is not set |
907 | # CONFIG_SSL_CLIENT is not set | 908 | CONFIG_SSL_CLIENT=y |
908 | # CONFIG_TC is not set | 909 | # CONFIG_TC is not set |
909 | # CONFIG_FEATURE_TC_INGRESS is not set | 910 | # CONFIG_FEATURE_TC_INGRESS is not set |
910 | # CONFIG_TCPSVD is not set | 911 | # CONFIG_TCPSVD is not set |
@@ -923,7 +924,7 @@ CONFIG_NC_SERVER=y | |||
923 | # CONFIG_FEATURE_TFTP_PUT is not set | 924 | # CONFIG_FEATURE_TFTP_PUT is not set |
924 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set | 925 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set |
925 | # CONFIG_TFTP_DEBUG is not set | 926 | # CONFIG_TFTP_DEBUG is not set |
926 | # CONFIG_TLS is not set | 927 | CONFIG_TLS=y |
927 | # CONFIG_TRACEROUTE is not set | 928 | # CONFIG_TRACEROUTE is not set |
928 | # CONFIG_TRACEROUTE6 is not set | 929 | # CONFIG_TRACEROUTE6 is not set |
929 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set | 930 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set |
@@ -934,9 +935,9 @@ CONFIG_NC_SERVER=y | |||
934 | CONFIG_WGET=y | 935 | CONFIG_WGET=y |
935 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y | 936 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y |
936 | # CONFIG_FEATURE_WGET_STATUSBAR is not set | 937 | # CONFIG_FEATURE_WGET_STATUSBAR is not set |
937 | # CONFIG_FEATURE_WGET_AUTHENTICATION is not set | 938 | CONFIG_FEATURE_WGET_AUTHENTICATION=y |
938 | # CONFIG_FEATURE_WGET_TIMEOUT is not set | 939 | # CONFIG_FEATURE_WGET_TIMEOUT is not set |
939 | # CONFIG_FEATURE_WGET_HTTPS is not set | 940 | CONFIG_FEATURE_WGET_HTTPS=y |
940 | # CONFIG_FEATURE_WGET_OPENSSL is not set | 941 | # CONFIG_FEATURE_WGET_OPENSSL is not set |
941 | CONFIG_WHOIS=y | 942 | CONFIG_WHOIS=y |
942 | # CONFIG_ZCIP is not set | 943 | # CONFIG_ZCIP is not set |
diff --git a/include/mingw.h b/include/mingw.h index 386540b37..e56e8f03d 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -111,6 +111,7 @@ 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); | ||
114 | int mingw_pclose(FILE *fd); | 115 | int mingw_pclose(FILE *fd); |
115 | #undef popen | 116 | #undef popen |
116 | #undef pclose | 117 | #undef pclose |
diff --git a/networking/ssl_client.c b/networking/ssl_client.c index eb84e7726..e56d82fc1 100644 --- a/networking/ssl_client.c +++ b/networking/ssl_client.c | |||
@@ -15,7 +15,12 @@ | |||
15 | //kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o | 15 | //kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o |
16 | 16 | ||
17 | //usage:#define ssl_client_trivial_usage | 17 | //usage:#define ssl_client_trivial_usage |
18 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
18 | //usage: "[-e] -s FD [-r FD] [-n SNI]" | 19 | //usage: "[-e] -s FD [-r FD] [-n SNI]" |
20 | //usage: ) | ||
21 | //usage: IF_PLATFORM_MINGW32( | ||
22 | //usage: "[-e] -h handle [-n SNI]" | ||
23 | //usage: ) | ||
19 | //usage:#define ssl_client_full_usage "" | 24 | //usage:#define ssl_client_full_usage "" |
20 | 25 | ||
21 | #include "libbb.h" | 26 | #include "libbb.h" |
@@ -26,15 +31,24 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv) | |||
26 | tls_state_t *tls; | 31 | tls_state_t *tls; |
27 | const char *sni = NULL; | 32 | const char *sni = NULL; |
28 | int opt; | 33 | int opt; |
34 | #if ENABLE_PLATFORM_MINGW32 | ||
35 | char *hstr = NULL; | ||
36 | HANDLE h; | ||
37 | #endif | ||
29 | 38 | ||
30 | // INIT_G(); | 39 | // INIT_G(); |
31 | 40 | ||
32 | tls = new_tls_state(); | 41 | tls = new_tls_state(); |
33 | opt = getopt32(argv, "es:#r:#n:", &tls->ofd, &tls->ifd, &sni); | 42 | #if !ENABLE_PLATFORM_MINGW32 |
43 | opt = getopt32(argv, "es:+r:+n:", &tls->ofd, &tls->ifd, &sni); | ||
44 | |||
34 | if (!(opt & (1<<2))) { | 45 | if (!(opt & (1<<2))) { |
35 | /* -r N defaults to -s N */ | 46 | /* -r N defaults to -s N */ |
36 | tls->ifd = tls->ofd; | 47 | tls->ifd = tls->ofd; |
37 | } | 48 | } |
49 | #else | ||
50 | opt = getopt32(argv, "eh:n:", &hstr, &sni); | ||
51 | #endif | ||
38 | 52 | ||
39 | if (!(opt & (3<<1))) { | 53 | if (!(opt & (3<<1))) { |
40 | if (!argv[1]) | 54 | if (!argv[1]) |
@@ -47,6 +61,13 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv) | |||
47 | sni = argv[1]; | 61 | sni = argv[1]; |
48 | tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); | 62 | tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); |
49 | } | 63 | } |
64 | #if ENABLE_PLATFORM_MINGW32 | ||
65 | else { | ||
66 | if (!hstr || sscanf(hstr, "%p", &h) != 1) | ||
67 | bb_error_msg_and_die("invalid handle"); | ||
68 | tls->ifd = tls->ofd = _open_osfhandle((intptr_t)h, _O_RDWR|_O_BINARY); | ||
69 | } | ||
70 | #endif | ||
50 | 71 | ||
51 | tls_handshake(tls, sni); | 72 | tls_handshake(tls, sni); |
52 | 73 | ||
diff --git a/networking/tls.c b/networking/tls.c index 99722cfb4..ec5a56d57 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -289,8 +289,14 @@ static void dump_tls_record(const void *vp, int len) | |||
289 | 289 | ||
290 | void tls_get_random(void *buf, unsigned len) | 290 | void tls_get_random(void *buf, unsigned len) |
291 | { | 291 | { |
292 | #if !ENABLE_PLATFORM_MINGW32 | ||
292 | if (len != open_read_close("/dev/urandom", buf, len)) | 293 | if (len != open_read_close("/dev/urandom", buf, len)) |
293 | xfunc_die(); | 294 | xfunc_die(); |
295 | #else | ||
296 | int fd = mingw_open("/dev/urandom", O_RDONLY|O_SPECIAL); | ||
297 | if (fd < 0 || len != read_close(fd, buf, len)) | ||
298 | xfunc_die(); | ||
299 | #endif | ||
294 | } | 300 | } |
295 | 301 | ||
296 | /* Nondestructively see the current hash value */ | 302 | /* Nondestructively see the current hash value */ |
diff --git a/networking/wget.c b/networking/wget.c index 150bc8e12..776894dca 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -714,6 +714,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
714 | #endif | 714 | #endif |
715 | 715 | ||
716 | #if ENABLE_FEATURE_WGET_HTTPS | 716 | #if ENABLE_FEATURE_WGET_HTTPS |
717 | # if !ENABLE_PLATFORM_MINGW32 | ||
717 | static void spawn_ssl_client(const char *host, int network_fd, int flags) | 718 | static void spawn_ssl_client(const char *host, int network_fd, int flags) |
718 | { | 719 | { |
719 | int sp[2]; | 720 | int sp[2]; |
@@ -763,6 +764,32 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
763 | close(sp[1]); | 764 | close(sp[1]); |
764 | xmove_fd(sp[0], network_fd); | 765 | xmove_fd(sp[0], network_fd); |
765 | } | 766 | } |
767 | # else | ||
768 | static void spawn_ssl_client(const char *host, int network_fd, int flags) | ||
769 | { | ||
770 | int fd1; | ||
771 | pid_t pid; | ||
772 | char *servername, *p, *cmd; | ||
773 | |||
774 | servername = xstrdup(host); | ||
775 | p = strrchr(servername, ':'); | ||
776 | if (p) *p = '\0'; | ||
777 | |||
778 | fflush_all(); | ||
779 | |||
780 | cmd = xasprintf("%s ssl_client -h %p -n %s%s", bb_busybox_exec_path, | ||
781 | (void *)_get_osfhandle(network_fd), servername, | ||
782 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); | ||
783 | |||
784 | if ( (fd1=mingw_popen2(cmd, &pid)) == -1 ) { | ||
785 | bb_perror_msg_and_die("can't execute ssl_client"); | ||
786 | } | ||
787 | |||
788 | free(cmd); | ||
789 | free(servername); | ||
790 | xmove_fd(fd1, network_fd); | ||
791 | } | ||
792 | # endif | ||
766 | #endif | 793 | #endif |
767 | 794 | ||
768 | static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa) | 795 | static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa) |
diff --git a/win32/popen.c b/win32/popen.c index 59f5ca9f0..c075e2144 100644 --- a/win32/popen.c +++ b/win32/popen.c | |||
@@ -288,6 +288,109 @@ finito: | |||
288 | return fd; | 288 | return fd; |
289 | } | 289 | } |
290 | 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; | ||
308 | } | ||
309 | |||
310 | /* find an unused pipe structure */ | ||
311 | if ( (p=find_pipe()) == NULL ) { | ||
312 | return -1; | ||
313 | } | ||
314 | |||
315 | /* Create the pipe */ | ||
316 | name = xasprintf("\\\\.\\pipe\\bb_pipe.%d.%d", getpid(), (int)(p-pipes)); | ||
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; | ||
337 | } | ||
338 | |||
339 | /* Make the parent end of the pipe non-inheritable */ | ||
340 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | ||
341 | |||
342 | /* Now create the child process */ | ||
343 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
344 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
345 | siStartInfo.wShowWindow = SW_HIDE; | ||
346 | siStartInfo.hStdInput = p->pipe[ic]; | ||
347 | siStartInfo.hStdOutput = p->pipe[ic]; | ||
348 | siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | ||
349 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | ||
350 | |||
351 | success = CreateProcess(NULL, | ||
352 | (LPTSTR)cmd, /* command line */ | ||
353 | NULL, /* process security attributes */ | ||
354 | NULL, /* primary thread security attributes */ | ||
355 | TRUE, /* handles are inherited */ | ||
356 | 0, /* creation flags */ | ||
357 | NULL, /* use parent's environment */ | ||
358 | NULL, /* use parent's current directory */ | ||
359 | &siStartInfo, /* STARTUPINFO pointer */ | ||
360 | &p->piProcInfo); /* receives PROCESS_INFORMATION */ | ||
361 | |||
362 | if ( !success ) { | ||
363 | goto finito; | ||
364 | } | ||
365 | |||
366 | /* close child end of pipe */ | ||
367 | CloseHandle(p->pipe[ic]); | ||
368 | p->pipe[ic] = INVALID_HANDLE_VALUE; | ||
369 | |||
370 | fd = _open_osfhandle((intptr_t)p->pipe[ip], _O_RDWR|_O_BINARY); | ||
371 | |||
372 | finito: | ||
373 | free(name); | ||
374 | if ( fd == -1 ) { | ||
375 | errno = err_win_to_posix(GetLastError()); | ||
376 | if ( p->pipe[0] != INVALID_HANDLE_VALUE ) { | ||
377 | CloseHandle(p->pipe[0]); | ||
378 | } | ||
379 | if ( p->pipe[1] != INVALID_HANDLE_VALUE ) { | ||
380 | CloseHandle(p->pipe[1]); | ||
381 | } | ||
382 | } | ||
383 | else { | ||
384 | p->mode = 'r'; | ||
385 | p->fd = fd; | ||
386 | if ( pid ) { | ||
387 | *pid = (pid_t)p->piProcInfo.dwProcessId; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | return fd; | ||
392 | } | ||
393 | |||
291 | int mingw_pclose(FILE *fp) | 394 | int mingw_pclose(FILE *fp) |
292 | { | 395 | { |
293 | int i, ip, fd; | 396 | int i, ip, fd; |