summaryrefslogtreecommitdiff
path: root/libusb/os/poll_windows.c
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2011-03-08 17:37:40 +0000
committerPeter Stuge <peter@stuge.se>2011-06-13 22:06:31 +0200
commit25fa63ea1cfe02e784cb62d3b869fd15e62b5b6e (patch)
tree28fd963cac2258f1644d5a416aa45171c840a104 /libusb/os/poll_windows.c
parent3ccd9bddec316ee4b867959fd7f616eb4d410997 (diff)
downloadlibusb-25fa63ea1cfe02e784cb62d3b869fd15e62b5b6e.tar.gz
Windows: Don't leak pipe fds
use _open() and _close() rather than _open_osfhandle() and CloseHandle() * use of CloseHandle() prevented the pipe fds from being relinquished on libusb_exit() * leaked fds could lead to the OS running out of new fds and LIBUSB_ERROR_NO_MEM being returned as a result * using _open() avoids _open_osfhandle() redef for cygwin * issue reported by Stephano Antonelli
Diffstat (limited to 'libusb/os/poll_windows.c')
-rw-r--r--libusb/os/poll_windows.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c
index 556ac84..b17b253 100644
--- a/libusb/os/poll_windows.c
+++ b/libusb/os/poll_windows.c
@@ -67,30 +67,12 @@
#if defined(__CYGWIN__)
// cygwin produces a warning unless these prototypes are defined
+extern int _open(char* name, int flags);
extern int _close(int fd);
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
-extern int cygwin_attach_handle_to_fd(char *name, int fd, HANDLE handle, int bin, int access_mode);
-// _open_osfhandle() is not available on cygwin, but we can emulate
-// it for our needs with cygwin_attach_handle_to_fd()
-static inline int _open_osfhandle(intptr_t osfhandle, int flags)
-{
- int access_mode;
- switch (flags) {
- case _O_RDONLY:
- access_mode = GENERIC_READ;
- break;
- case _O_WRONLY:
- access_mode = GENERIC_WRITE;
- break;
- case _O_RDWR:
- access_mode = GENERIC_READ|GENERIC_WRITE;
- break;
- default:
- usbi_err(NULL, "unsupported access mode");
- return -1;
- }
- return cygwin_attach_handle_to_fd("/dev/null", -1, (HANDLE)osfhandle, -1, access_mode);
-}
+#define NUL_DEVICE "/dev/null"
+#else
+#define NUL_DEVICE "NUL"
#endif
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
@@ -288,7 +270,6 @@ void exit_polling(void)
int usbi_pipe(int filedes[2])
{
int i;
- HANDLE handle;
OVERLAPPED* overlapped;
CHECK_INIT_POLLING;
@@ -302,12 +283,11 @@ int usbi_pipe(int filedes[2])
overlapped->InternalHigh = 0;
// Read end of the "pipe"
- handle = CreateFileA("NUL", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- usbi_err(NULL, "could not create pipe: errcode %d", (int)GetLastError());
+ filedes[0] = _open(NUL_DEVICE, _O_WRONLY);
+ if (filedes[0] < 0) {
+ usbi_err(NULL, "could not create pipe: errno %d", errno);
goto out1;
}
- filedes[0] = _open_osfhandle((intptr_t)handle, _O_RDONLY);
// We can use the same handle for both ends
filedes[1] = filedes[0];
poll_dbg("pipe filedes = %d", filedes[0]);
@@ -328,7 +308,7 @@ int usbi_pipe(int filedes[2])
}
poll_fd[i].fd = filedes[0];
- poll_fd[i].handle = handle;
+ poll_fd[i].handle = DUMMY_HANDLE;
poll_fd[i].overlapped = overlapped;
// There's no polling on the write end, so we just use READ for our needs
poll_fd[i].rw = RW_READ;
@@ -340,7 +320,7 @@ int usbi_pipe(int filedes[2])
CloseHandle(overlapped->hEvent);
out2:
- CloseHandle(handle);
+ _close(filedes[0]);
out1:
free(overlapped);
return -1;
@@ -383,9 +363,9 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
wfd.rw = RW_WRITE;
}
- // Ensure that we get a non system conflicting unique fd
- fd = _open_osfhandle((intptr_t)CreateFileA("NUL", 0, 0,
- NULL, OPEN_EXISTING, 0, NULL), _O_RDWR);
+ // Ensure that we get a non system conflicting unique fd, using
+ // the same fd attribution system as the pipe ends
+ fd = _open(NUL_DEVICE, _O_WRONLY);
if (fd < 0) {
return INVALID_WINFD;
}
@@ -770,10 +750,9 @@ int usbi_close(int fd)
CloseHandle(poll_fd[_index].overlapped->hEvent);
free(poll_fd[_index].overlapped);
}
- if (CloseHandle(poll_fd[_index].handle) == 0) {
+ r = _close(poll_fd[_index].fd);
+ if (r != 0) {
errno = EIO;
- } else {
- r = 0;
}
poll_fd[_index] = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[_index].mutex);