commit cb81f67209f66d1a4bf189ced17819d492a7ba81 Author: Paolo Bonzini Date: Tue Aug 4 18:06:07 2009 +0200 Work around mysterious Wine bug in poll/select. * lib/poll.c: Do not bother checking for readability of console handles if not requested. Somehow fixes Wine. * lib/select.c: Likewise. diff --git a/ChangeLog b/ChangeLog index 56e11fa..c54aef5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-08-04 Paolo Bonzini + + Work around mysterious Wine bug in poll/select. + * lib/poll.c: Do not bother checking for readability + of console handles if not requested. Somehow fixes Wine. + * lib/select.c: Likewise. + 2009-07-25 Paolo Bonzini New module pipe-filter. diff --git a/lib/poll.c b/lib/poll.c index ed76098..9c72a4a 100644 --- a/lib/poll.c +++ b/lib/poll.c @@ -67,6 +67,23 @@ #ifdef WIN32_NATIVE +#define IsHandleConsole(h) (((long) (h) & 3) == 3) + +static BOOL +IsHandleSocket(HANDLE h) +{ + WSANETWORKEVENTS ev; + + if (IsHandleConsole (h)) + return FALSE; + + /* Under Wine, it seems that getsockopt returns 0 for pipes too. + WSAEnumNetworkEvents instead distinguishes the two correctly. */ + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); + return ev.lNetworkEvents != 0xDEADBEEF; +} + /* Declare data structures for ntdll functions. */ typedef struct _FILE_PIPE_LOCAL_INFORMATION { ULONG NamedPipeType; @@ -156,6 +173,9 @@ win32_compute_revents (HANDLE h, int sought) return happened; case FILE_TYPE_CHAR: + if (!(sought & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND))) + break; + ret = WaitForSingleObject (h, 0); if (ret == WAIT_OBJECT_0) { @@ -439,12 +459,7 @@ poll (pfd, nfd, timeout) h = (HANDLE) _get_osfhandle (pfd[i].fd); assert (h != NULL); - - /* Under Wine, it seems that getsockopt returns 0 for pipes too. - WSAEnumNetworkEvents instead distinguishes the two correctly. */ - ev.lNetworkEvents = 0xDEADBEEF; - WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); - if (ev.lNetworkEvents != 0xDEADBEEF) + if (IsHandleSocket (h)) { int requested = FD_CLOSE; diff --git a/lib/select.c b/lib/select.c index 8496c15..b3da42d 100644 --- a/lib/select.c +++ b/lib/select.c @@ -76,6 +76,23 @@ typedef DWORD (WINAPI *PNtQueryInformationFile) #define PIPE_BUF 512 #endif +#define IsHandleConsole(h) (((long) (h) & 3) == 3) + +static BOOL +IsHandleSocket(HANDLE h) +{ + WSANETWORKEVENTS ev; + + if (IsHandleConsole (h)) + return FALSE; + + /* Under Wine, it seems that getsockopt returns 0 for pipes too. + WSAEnumNetworkEvents instead distinguishes the two correctly. */ + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); + return ev.lNetworkEvents != 0xDEADBEEF; +} + /* Compute output fd_sets for libc descriptor FD (whose Win32 handle is H). */ static int @@ -138,8 +155,11 @@ win32_poll_handle (HANDLE h, int fd, struct bitset *rbits, struct bitset *wbits, break; case FILE_TYPE_CHAR: - ret = WaitForSingleObject (h, 0); write = TRUE; + if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1))))) + break; + + ret = WaitForSingleObject (h, 0); if (ret == WAIT_OBJECT_0) { nbuffer = avail = 0; @@ -285,11 +305,7 @@ rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, return -1; } - /* Under Wine, it seems that getsockopt returns 0 for pipes too. - WSAEnumNetworkEvents instead distinguishes the two correctly. */ - ev.lNetworkEvents = 0xDEADBEEF; - WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); - if (ev.lNetworkEvents != 0xDEADBEEF) + if (IsHandleSocket (h)) { int requested = FD_CLOSE;