aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-02-13 13:11:57 +0000
committerRon Yorston <rmy@pobox.com>2018-02-13 13:11:57 +0000
commit054a022f7c9a5cdf5ed44ffcf48e214a5b11c913 (patch)
tree649c2cd9e4e8866366eeccafc1891a785a1db03f
parent8bc8da2577c0f0c3b4f33b3190de57a2b4d13a24 (diff)
downloadbusybox-w32-054a022f7c9a5cdf5ed44ffcf48e214a5b11c913.tar.gz
busybox-w32-054a022f7c9a5cdf5ed44ffcf48e214a5b11c913.tar.bz2
busybox-w32-054a022f7c9a5cdf5ed44ffcf48e214a5b11c913.zip
win32: update poll implementation to match latest gnulib version
-rw-r--r--win32/poll.c416
1 files changed, 207 insertions, 209 deletions
diff --git a/win32/poll.c b/win32/poll.c
index 935b92423..3294fdc96 100644
--- a/win32/poll.c
+++ b/win32/poll.c
@@ -1,7 +1,7 @@
1/* Emulation for poll(2) 1/* Emulation for poll(2)
2 Contributed by Paolo Bonzini. 2 Contributed by Paolo Bonzini.
3 3
4 Copyright 2001-2003, 2006-2011 Free Software Foundation, Inc. 4 Copyright 2001-2003, 2006-2018 Free Software Foundation, Inc.
5 5
6 This file is part of gnulib. 6 This file is part of gnulib.
7 7
@@ -16,8 +16,7 @@
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License along 18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, 19 with this program; if not, see <https://www.gnu.org/licenses/>. */
20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21 20
22/* Tell gcc not to warn about the (nfd < 0) tests, below. */ 21/* Tell gcc not to warn about the (nfd < 0) tests, below. */
23#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ 22#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
@@ -36,6 +35,7 @@
36#include <assert.h> 35#include <assert.h>
37 36
38#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 37#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38# define WINDOWS_NATIVE
39# define WIN32_NATIVE 39# define WIN32_NATIVE
40# if defined (_MSC_VER) 40# if defined (_MSC_VER)
41# define _WIN32_WINNT 0x0502 41# define _WIN32_WINNT 0x0502
@@ -47,11 +47,12 @@
47# include <conio.h> 47# include <conio.h>
48#else 48#else
49# include <sys/time.h> 49# include <sys/time.h>
50# include <sys/socket.h>
51# include <sys/select.h>
52# include <unistd.h> 50# include <unistd.h>
53#endif 51#endif
54 52
53#include <sys/select.h>
54#include <sys/socket.h>
55
55#ifdef HAVE_SYS_IOCTL_H 56#ifdef HAVE_SYS_IOCTL_H
56# include <sys/ioctl.h> 57# include <sys/ioctl.h>
57#endif 58#endif
@@ -70,9 +71,21 @@
70# define MSG_PEEK 0 71# define MSG_PEEK 0
71#endif 72#endif
72 73
73#ifdef WIN32_NATIVE 74#ifdef WINDOWS_NATIVE
75
76/* Here we need the recv() function from Windows, that takes a SOCKET as
77 first argument, not any possible gnulib override. */
78# undef recv
74 79
75#define IsConsoleHandle(h) (((intptr_t) (h) & 3) == 3) 80/* Here we need the select() function from Windows, because we pass bit masks
81 of SOCKETs, not bit masks of FDs. */
82# undef select
83
84static BOOL IsConsoleHandle (HANDLE h)
85{
86 DWORD mode;
87 return GetConsoleMode (h, &mode) != 0;
88}
76 89
77static BOOL 90static BOOL
78IsSocketHandle (HANDLE h) 91IsSocketHandle (HANDLE h)
@@ -117,7 +130,7 @@ typedef enum _FILE_INFORMATION_CLASS {
117} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; 130} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
118 131
119typedef DWORD (WINAPI *PNtQueryInformationFile) 132typedef DWORD (WINAPI *PNtQueryInformationFile)
120 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS); 133 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
121 134
122# ifndef PIPE_BUF 135# ifndef PIPE_BUF
123# define PIPE_BUF 512 136# define PIPE_BUF 512
@@ -127,7 +140,7 @@ typedef DWORD (WINAPI *PNtQueryInformationFile)
127 for the handle, eliminate them from *P_SOUGHT. */ 140 for the handle, eliminate them from *P_SOUGHT. */
128 141
129static int 142static int
130win32_compute_revents (HANDLE h, int *p_sought) 143windows_compute_revents (HANDLE h, int *p_sought)
131{ 144{
132 int i, ret, happened; 145 int i, ret, happened;
133 INPUT_RECORD *irbuffer; 146 INPUT_RECORD *irbuffer;
@@ -142,81 +155,82 @@ win32_compute_revents (HANDLE h, int *p_sought)
142 { 155 {
143 case FILE_TYPE_PIPE: 156 case FILE_TYPE_PIPE:
144 if (!once_only) 157 if (!once_only)
145 { 158 {
146 NtQueryInformationFile = (PNtQueryInformationFile) 159 NtQueryInformationFile = (PNtQueryInformationFile)
147 GetProcAddress (GetModuleHandle ("ntdll.dll"), 160 GetProcAddress (GetModuleHandle ("ntdll.dll"),
148 "NtQueryInformationFile"); 161 "NtQueryInformationFile");
149 once_only = TRUE; 162 once_only = TRUE;
150 } 163 }
151 164
152 happened = 0; 165 happened = 0;
153 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0) 166 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
154 { 167 {
155 if (avail) 168 if (avail)
156 happened |= *p_sought & (POLLIN | POLLRDNORM); 169 happened |= *p_sought & (POLLIN | POLLRDNORM);
157 } 170 }
158 else if (GetLastError () == ERROR_BROKEN_PIPE) 171 else if (GetLastError () == ERROR_BROKEN_PIPE)
159 happened |= POLLHUP; 172 happened |= POLLHUP;
160 173
161 else 174 else
162 { 175 {
163 /* It was the write-end of the pipe. Check if it is writable. 176 /* It was the write-end of the pipe. Check if it is writable.
164 If NtQueryInformationFile fails, optimistically assume the pipe is 177 If NtQueryInformationFile fails, optimistically assume the pipe is
165 writable. This could happen on Win9x, where NtQueryInformationFile 178 writable. This could happen on Windows 9x, where
166 is not available, or if we inherit a pipe that doesn't permit 179 NtQueryInformationFile is not available, or if we inherit a pipe
167 FILE_READ_ATTRIBUTES access on the write end (I think this should 180 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
168 not happen since WinXP SP2; WINE seems fine too). Otherwise, 181 (I think this should not happen since Windows XP SP2; WINE seems
169 ensure that enough space is available for atomic writes. */ 182 fine too). Otherwise, ensure that enough space is available for
170 memset (&iosb, 0, sizeof (iosb)); 183 atomic writes. */
171 memset (&fpli, 0, sizeof (fpli)); 184 memset (&iosb, 0, sizeof (iosb));
172 185 memset (&fpli, 0, sizeof (fpli));
173 if (!NtQueryInformationFile 186
174 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli), 187 if (!NtQueryInformationFile
175 FilePipeLocalInformation) 188 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
176 || fpli.WriteQuotaAvailable >= PIPE_BUF 189 FilePipeLocalInformation)
177 || (fpli.OutboundQuota < PIPE_BUF && 190 || fpli.WriteQuotaAvailable >= PIPE_BUF
178 fpli.WriteQuotaAvailable == fpli.OutboundQuota)) 191 || (fpli.OutboundQuota < PIPE_BUF &&
179 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND); 192 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
180 } 193 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
194 }
181 return happened; 195 return happened;
182 196
183 case FILE_TYPE_CHAR: 197 case FILE_TYPE_CHAR:
184 ret = WaitForSingleObject (h, 0); 198 ret = WaitForSingleObject (h, 0);
185 if (!IsConsoleHandle (h)) 199 if (!IsConsoleHandle (h))
186 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0; 200 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
187 201
188 nbuffer = avail = 0; 202 nbuffer = avail = 0;
189 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer); 203 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
190 if (bRet) 204 if (bRet)
191 { 205 {
192 /* Input buffer. */ 206 /* Input buffer. */
193 *p_sought &= POLLIN | POLLRDNORM; 207 *p_sought &= POLLIN | POLLRDNORM;
194 if (nbuffer == 0) 208 if (nbuffer == 0)
195 return POLLHUP; 209 return POLLHUP;
196 if (!*p_sought) 210 if (!*p_sought)
197 return 0; 211 return 0;
198 212
199 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD)); 213 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
200 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail); 214 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
201 if (!bRet || avail == 0) 215 if (!bRet || avail == 0)
202 return POLLHUP; 216 return POLLHUP;
203 217
204 for (i = 0; i < avail; i++) 218 for (i = 0; i < avail; i++)
205 if (irbuffer[i].EventType == KEY_EVENT) 219 if (irbuffer[i].EventType == KEY_EVENT)
206 return *p_sought; 220 return *p_sought;
207 return 0; 221 return 0;
208 } 222 }
209 else 223 else
210 { 224 {
211 /* Screen buffer. */ 225 /* Screen buffer. */
212 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND; 226 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
213 return *p_sought; 227 return *p_sought;
214 } 228 }
215 229
216 default: 230 default:
217 ret = WaitForSingleObject (h, 0); 231 ret = WaitForSingleObject (h, 0);
218 if (ret == WAIT_OBJECT_0) 232 if (ret == WAIT_OBJECT_0)
219 return *p_sought & ~(POLLPRI | POLLRDBAND); 233 return *p_sought & ~(POLLPRI | POLLRDBAND);
220 234
221 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND); 235 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
222 } 236 }
@@ -225,7 +239,7 @@ win32_compute_revents (HANDLE h, int *p_sought)
225/* Convert fd_sets returned by select into revents values. */ 239/* Convert fd_sets returned by select into revents values. */
226 240
227static int 241static int
228win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents) 242windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
229{ 243{
230 int happened = 0; 244 int happened = 0;
231 245
@@ -243,15 +257,15 @@ win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
243 WSASetLastError (0); 257 WSASetLastError (0);
244 258
245 if (r > 0 || error == WSAENOTCONN) 259 if (r > 0 || error == WSAENOTCONN)
246 happened |= (POLLIN | POLLRDNORM) & sought; 260 happened |= (POLLIN | POLLRDNORM) & sought;
247 261
248 /* Distinguish hung-up sockets from other errors. */ 262 /* Distinguish hung-up sockets from other errors. */
249 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET 263 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
250 || error == WSAECONNABORTED || error == WSAENETRESET) 264 || error == WSAECONNABORTED || error == WSAENETRESET)
251 happened |= POLLHUP; 265 happened |= POLLHUP;
252 266
253 else 267 else
254 happened |= POLLERR; 268 happened |= POLLERR;
255 } 269 }
256 270
257 if (lNetworkEvents & (FD_WRITE | FD_CONNECT)) 271 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
@@ -277,33 +291,37 @@ compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
277 291
278# if defined __MACH__ && defined __APPLE__ 292# if defined __MACH__ && defined __APPLE__
279 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK 293 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
280 for some kinds of descriptors. Detect if this descriptor is a 294 for some kinds of descriptors. Detect if this descriptor is a
281 connected socket, a server socket, or something else using a 295 connected socket, a server socket, or something else using a
282 0-byte recv, and use ioctl(2) to detect POLLHUP. */ 296 0-byte recv, and use ioctl(2) to detect POLLHUP. */
283 r = recv (fd, NULL, 0, MSG_PEEK); 297 r = recv (fd, NULL, 0, MSG_PEEK);
284 socket_errno = (r < 0) ? errno : 0; 298 socket_errno = (r < 0) ? errno : 0;
285 if (r == 0 || socket_errno == ENOTSOCK) 299 if (r == 0 || socket_errno == ENOTSOCK)
286 ioctl (fd, FIONREAD, &r); 300 ioctl (fd, FIONREAD, &r);
287# else 301# else
288 char data[64]; 302 char data[64];
289 r = recv (fd, data, sizeof (data), MSG_PEEK); 303 r = recv (fd, data, sizeof (data), MSG_PEEK);
290 socket_errno = (r < 0) ? errno : 0; 304 socket_errno = (r < 0) ? errno : 0;
291# endif 305# endif
292 if (r == 0) 306 if (r == 0)
293 happened |= POLLHUP; 307 happened |= POLLHUP;
294 308
295 /* If the event happened on an unconnected server socket, 309 /* If the event happened on an unconnected server socket,
296 that's fine. */ 310 that's fine. */
297 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN)) 311 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
298 happened |= (POLLIN | POLLRDNORM) & sought; 312 happened |= (POLLIN | POLLRDNORM) & sought;
299 313
300 /* Distinguish hung-up sockets from other errors. */ 314 /* Distinguish hung-up sockets from other errors. */
301 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET 315 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
302 || socket_errno == ECONNABORTED || socket_errno == ENETRESET) 316 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
303 happened |= POLLHUP; 317 happened |= POLLHUP;
318
319 /* some systems can't use recv() on non-socket, including HP NonStop */
320 else if (socket_errno == ENOTSOCK)
321 happened |= (POLLIN | POLLRDNORM) & sought;
304 322
305 else 323 else
306 happened |= POLLERR; 324 happened |= POLLERR;
307 } 325 }
308 326
309 if (FD_ISSET (fd, wfds)) 327 if (FD_ISSET (fd, wfds))
@@ -319,37 +337,26 @@ compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
319int 337int
320poll (struct pollfd *pfd, nfds_t nfd, int timeout) 338poll (struct pollfd *pfd, nfds_t nfd, int timeout)
321{ 339{
322#ifndef WIN32_NATIVE 340#ifndef WINDOWS_NATIVE
323 fd_set rfds, wfds, efds; 341 fd_set rfds, wfds, efds;
324 struct timeval tv; 342 struct timeval tv;
325 struct timeval *ptv; 343 struct timeval *ptv;
326 int maxfd, rc; 344 int maxfd, rc;
327 nfds_t i; 345 nfds_t i;
328 346
329# ifdef _SC_OPEN_MAX 347 if (nfd > INT_MAX)
330 static int sc_open_max = -1;
331
332 if (nfd < 0
333 || (nfd > sc_open_max
334 && (sc_open_max != -1
335 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
336 { 348 {
337 errno = EINVAL; 349 errno = EINVAL;
338 return -1; 350 return -1;
339 } 351 }
340# else /* !_SC_OPEN_MAX */ 352 /* Don't check directly for NFD greater than OPEN_MAX. Any practical use
341# ifdef OPEN_MAX 353 of a too-large NFD is caught by one of the other checks below, and
342 if (nfd < 0 || nfd > OPEN_MAX) 354 checking directly for getdtablesize is too much of a portability
343 { 355 and/or performance and/or correctness hassle. */
344 errno = EINVAL;
345 return -1;
346 }
347# endif /* OPEN_MAX -- else, no check is needed */
348# endif /* !_SC_OPEN_MAX */
349 356
350 /* EFAULT is not necessary to implement, but let's do it in the 357 /* EFAULT is not necessary to implement, but let's do it in the
351 simplest case. */ 358 simplest case. */
352 if (!pfd) 359 if (!pfd && nfd)
353 { 360 {
354 errno = EFAULT; 361 errno = EFAULT;
355 return -1; 362 return -1;
@@ -385,30 +392,26 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
385 for (i = 0; i < nfd; i++) 392 for (i = 0; i < nfd; i++)
386 { 393 {
387 if (pfd[i].fd < 0) 394 if (pfd[i].fd < 0)
388 continue; 395 continue;
389 396 if (maxfd < pfd[i].fd)
397 {
398 maxfd = pfd[i].fd;
399 if (FD_SETSIZE <= maxfd)
400 {
401 errno = EINVAL;
402 return -1;
403 }
404 }
390 if (pfd[i].events & (POLLIN | POLLRDNORM)) 405 if (pfd[i].events & (POLLIN | POLLRDNORM))
391 FD_SET (pfd[i].fd, &rfds); 406 FD_SET (pfd[i].fd, &rfds);
392 407
393 /* see select(2): "the only exceptional condition detectable 408 /* see select(2): "the only exceptional condition detectable
394 is out-of-band data received on a socket", hence we push 409 is out-of-band data received on a socket", hence we push
395 POLLWRBAND events onto wfds instead of efds. */ 410 POLLWRBAND events onto wfds instead of efds. */
396 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) 411 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
397 FD_SET (pfd[i].fd, &wfds); 412 FD_SET (pfd[i].fd, &wfds);
398 if (pfd[i].events & (POLLPRI | POLLRDBAND)) 413 if (pfd[i].events & (POLLPRI | POLLRDBAND))
399 FD_SET (pfd[i].fd, &efds); 414 FD_SET (pfd[i].fd, &efds);
400 if (pfd[i].fd >= maxfd
401 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
402 | POLLRDNORM | POLLRDBAND
403 | POLLWRNORM | POLLWRBAND)))
404 {
405 maxfd = pfd[i].fd;
406 if (maxfd > FD_SETSIZE)
407 {
408 errno = EOVERFLOW;
409 return -1;
410 }
411 }
412 } 415 }
413 416
414 /* examine fd sets */ 417 /* examine fd sets */
@@ -419,18 +422,13 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
419 /* establish results */ 422 /* establish results */
420 rc = 0; 423 rc = 0;
421 for (i = 0; i < nfd; i++) 424 for (i = 0; i < nfd; i++)
422 if (pfd[i].fd < 0) 425 {
423 pfd[i].revents = 0; 426 pfd[i].revents = (pfd[i].fd < 0
424 else 427 ? 0
425 { 428 : compute_revents (pfd[i].fd, pfd[i].events,
426 int happened = compute_revents (pfd[i].fd, pfd[i].events, 429 &rfds, &wfds, &efds));
427 &rfds, &wfds, &efds); 430 rc += pfd[i].revents != 0;
428 if (happened) 431 }
429 {
430 pfd[i].revents = happened;
431 rc++;
432 }
433 }
434 432
435 return rc; 433 return rc;
436#else 434#else
@@ -445,7 +443,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
445 int rc = 0; 443 int rc = 0;
446 nfds_t i; 444 nfds_t i;
447 445
448 if (nfd < 0 || timeout < -1) 446 if (nfd > INT_MAX || timeout < -1)
449 { 447 {
450 errno = EINVAL; 448 errno = EINVAL;
451 return -1; 449 return -1;
@@ -467,55 +465,55 @@ restart:
467 int sought = pfd[i].events; 465 int sought = pfd[i].events;
468 pfd[i].revents = 0; 466 pfd[i].revents = 0;
469 if (pfd[i].fd < 0) 467 if (pfd[i].fd < 0)
470 continue; 468 continue;
471 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND 469 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
472 | POLLPRI | POLLRDBAND))) 470 | POLLPRI | POLLRDBAND)))
473 continue; 471 continue;
474 472
475 h = (HANDLE) _get_osfhandle (pfd[i].fd); 473 h = (HANDLE) _get_osfhandle (pfd[i].fd);
476 assert (h != NULL); 474 assert (h != NULL);
477 if (IsSocketHandle (h)) 475 if (IsSocketHandle (h))
478 { 476 {
479 int requested = FD_CLOSE; 477 int requested = FD_CLOSE;
480 478
481 /* see above; socket handles are mapped onto select. */ 479 /* see above; socket handles are mapped onto select. */
482 if (sought & (POLLIN | POLLRDNORM)) 480 if (sought & (POLLIN | POLLRDNORM))
483 { 481 {
484 requested |= FD_READ | FD_ACCEPT; 482 requested |= FD_READ | FD_ACCEPT;
485 FD_SET ((SOCKET) h, &rfds); 483 FD_SET ((SOCKET) h, &rfds);
486 } 484 }
487 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND)) 485 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
488 { 486 {
489 requested |= FD_WRITE | FD_CONNECT; 487 requested |= FD_WRITE | FD_CONNECT;
490 FD_SET ((SOCKET) h, &wfds); 488 FD_SET ((SOCKET) h, &wfds);
491 } 489 }
492 if (sought & (POLLPRI | POLLRDBAND)) 490 if (sought & (POLLPRI | POLLRDBAND))
493 { 491 {
494 requested |= FD_OOB; 492 requested |= FD_OOB;
495 FD_SET ((SOCKET) h, &xfds); 493 FD_SET ((SOCKET) h, &xfds);
496 } 494 }
497 495
498 if (requested) 496 if (requested)
499 WSAEventSelect ((SOCKET) h, hEvent, requested); 497 WSAEventSelect ((SOCKET) h, hEvent, requested);
500 } 498 }
501 else 499 else
502 { 500 {
503 /* Poll now. If we get an event, do not poll again. Also, 501 /* Poll now. If we get an event, do not poll again. Also,
504 screen buffer handles are waitable, and they'll block until 502 screen buffer handles are waitable, and they'll block until
505 a character is available. win32_compute_revents eliminates 503 a character is available. windows_compute_revents eliminates
506 bits for the "wrong" direction. */ 504 bits for the "wrong" direction. */
507 pfd[i].revents = win32_compute_revents (h, &sought); 505 pfd[i].revents = windows_compute_revents (h, &sought);
508 if (sought) 506 if (sought)
509 handle_array[nhandles++] = h; 507 handle_array[nhandles++] = h;
510 if (pfd[i].revents) 508 if (pfd[i].revents)
511 timeout = 0; 509 timeout = 0;
512 } 510 }
513 } 511 }
514 512
515 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0) 513 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
516 { 514 {
517 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but 515 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
518 no need to call select again. */ 516 no need to call select again. */
519 poll_again = FALSE; 517 poll_again = FALSE;
520 wait_timeout = 0; 518 wait_timeout = 0;
521 } 519 }
@@ -523,28 +521,28 @@ restart:
523 { 521 {
524 poll_again = TRUE; 522 poll_again = TRUE;
525 if (timeout == INFTIM) 523 if (timeout == INFTIM)
526 wait_timeout = INFINITE; 524 wait_timeout = INFINITE;
527 else 525 else
528 wait_timeout = timeout; 526 wait_timeout = timeout;
529 } 527 }
530 528
531 for (;;) 529 for (;;)
532 { 530 {
533 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE, 531 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
534 wait_timeout, QS_ALLINPUT); 532 wait_timeout, QS_ALLINPUT);
535 533
536 if (ret == WAIT_OBJECT_0 + nhandles) 534 if (ret == WAIT_OBJECT_0 + nhandles)
537 { 535 {
538 /* new input of some other kind */ 536 /* new input of some other kind */
539 BOOL bRet; 537 BOOL bRet;
540 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0) 538 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
541 { 539 {
542 TranslateMessage (&msg); 540 TranslateMessage (&msg);
543 DispatchMessage (&msg); 541 DispatchMessage (&msg);
544 } 542 }
545 } 543 }
546 else 544 else
547 break; 545 break;
548 } 546 }
549 547
550 if (poll_again) 548 if (poll_again)
@@ -558,46 +556,46 @@ restart:
558 int happened; 556 int happened;
559 557
560 if (pfd[i].fd < 0) 558 if (pfd[i].fd < 0)
561 continue; 559 continue;
562 if (!(pfd[i].events & (POLLIN | POLLRDNORM | 560 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
563 POLLOUT | POLLWRNORM | POLLWRBAND))) 561 POLLOUT | POLLWRNORM | POLLWRBAND)))
564 continue; 562 continue;
565 563
566 h = (HANDLE) _get_osfhandle (pfd[i].fd); 564 h = (HANDLE) _get_osfhandle (pfd[i].fd);
567 if (h != handle_array[nhandles]) 565 if (h != handle_array[nhandles])
568 { 566 {
569 /* It's a socket. */ 567 /* It's a socket. */
570 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); 568 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
571 WSAEventSelect ((SOCKET) h, 0, 0); 569 WSAEventSelect ((SOCKET) h, 0, 0);
572 570
573 /* If we're lucky, WSAEnumNetworkEvents already provided a way 571 /* If we're lucky, WSAEnumNetworkEvents already provided a way
574 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */ 572 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
575 if (FD_ISSET ((SOCKET) h, &rfds) 573 if (FD_ISSET ((SOCKET) h, &rfds)
576 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT))) 574 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
577 ev.lNetworkEvents |= FD_READ | FD_ACCEPT; 575 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
578 if (FD_ISSET ((SOCKET) h, &wfds)) 576 if (FD_ISSET ((SOCKET) h, &wfds))
579 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT; 577 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
580 if (FD_ISSET ((SOCKET) h, &xfds)) 578 if (FD_ISSET ((SOCKET) h, &xfds))
581 ev.lNetworkEvents |= FD_OOB; 579 ev.lNetworkEvents |= FD_OOB;
582 580
583 happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events, 581 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
584 ev.lNetworkEvents); 582 ev.lNetworkEvents);
585 } 583 }
586 else 584 else
587 { 585 {
588 /* Not a socket. */ 586 /* Not a socket. */
589 int sought = pfd[i].events; 587 int sought = pfd[i].events;
590 happened = win32_compute_revents (h, &sought); 588 happened = windows_compute_revents (h, &sought);
591 nhandles++; 589 nhandles++;
592 } 590 }
593 591
594 if ((pfd[i].revents |= happened) != 0) 592 if ((pfd[i].revents |= happened) != 0)
595 rc++; 593 rc++;
596 } 594 }
597 595
598 if (!rc && timeout == INFTIM) 596 if (!rc && timeout == INFTIM)
599 { 597 {
600 SwitchToThread(); 598 SleepEx (1, TRUE);
601 goto restart; 599 goto restart;
602 } 600 }
603 601