diff options
Diffstat (limited to 'otherlibs/win32unix')
-rw-r--r-- | otherlibs/win32unix/channels.c | 1 | ||||
-rw-r--r-- | otherlibs/win32unix/close.c | 17 |
2 files changed, 15 insertions, 3 deletions
diff --git a/otherlibs/win32unix/channels.c b/otherlibs/win32unix/channels.c index 1c2cd2734..56a19c7dc 100644 --- a/otherlibs/win32unix/channels.c +++ b/otherlibs/win32unix/channels.c @@ -30,6 +30,7 @@ int win_CRT_fd_of_filedescr(value handle) } else { int fd = _open_osfhandle((long) Handle_val(handle), O_BINARY); if (fd == -1) uerror("channel_of_descr", Nothing); + CRT_fd_val(handle) = fd; return fd; } } diff --git a/otherlibs/win32unix/close.c b/otherlibs/win32unix/close.c index 48cd60e7a..21254ef1e 100644 --- a/otherlibs/win32unix/close.c +++ b/otherlibs/win32unix/close.c @@ -15,6 +15,9 @@ #include <mlvalues.h> #include "unixsupport.h" +#include <io.h> + +extern int _close(int); CAMLprim value unix_close(value fd) { @@ -24,9 +27,17 @@ CAMLprim value unix_close(value fd) uerror("close", Nothing); } } else { - if (! CloseHandle(Handle_val(fd))) { - win32_maperr(GetLastError()); - uerror("close", Nothing); + /* If we have an fd then closing it also closes + * the underlying handle. Also, closing only + * the handle and not the fd leads to fd leaks. */ + if (CRT_fd_val(fd) != NO_CRT_FD) { + if (_close(CRT_fd_val(fd)) != 0) + uerror("close", Nothing); + } else { + if (! CloseHandle(Handle_val(fd))) { + win32_maperr(GetLastError()); + uerror("close", Nothing); + } } } return Val_unit; |