summaryrefslogtreecommitdiffstats
path: root/otherlibs/win32unix
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/win32unix')
-rw-r--r--otherlibs/win32unix/channels.c1
-rw-r--r--otherlibs/win32unix/close.c17
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;