1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2016 Free Software Foundation, Inc.
6 This file is part of gnulib.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, see <http://www.gnu.org/licenses/>. */
21 /* Tell gcc not to warn about the (nfd < 0) tests, below. */
22 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
23 # pragma GCC diagnostic ignored "-Wtype-limits"
29 #include <sys/types.h>
37 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38 # define WINDOWS_NATIVE
39 # include <winsock2.h>
44 # include "msvc-nothrow.h"
46 # include <sys/time.h>
50 #include <sys/select.h>
51 #include <sys/socket.h>
53 #ifdef HAVE_SYS_IOCTL_H
54 # include <sys/ioctl.h>
56 #ifdef HAVE_SYS_FILIO_H
57 # include <sys/filio.h>
68 /* BeOS does not have MSG_PEEK. */
75 static BOOL IsConsoleHandle (HANDLE h)
78 return GetConsoleMode (h, &mode) != 0;
82 IsSocketHandle (HANDLE h)
86 if (IsConsoleHandle (h))
89 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
90 WSAEnumNetworkEvents instead distinguishes the two correctly. */
91 ev.lNetworkEvents = 0xDEADBEEF;
92 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
93 return ev.lNetworkEvents != 0xDEADBEEF;
96 /* Declare data structures for ntdll functions. */
97 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
99 ULONG NamedPipeConfiguration;
100 ULONG MaximumInstances;
101 ULONG CurrentInstances;
103 ULONG ReadDataAvailable;
105 ULONG WriteQuotaAvailable;
106 ULONG NamedPipeState;
108 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
110 typedef struct _IO_STATUS_BLOCK
116 ULONG_PTR Information;
117 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
119 typedef enum _FILE_INFORMATION_CLASS {
120 FilePipeLocalInformation = 24
121 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
123 typedef DWORD (WINAPI *PNtQueryInformationFile)
124 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
127 # define PIPE_BUF 512
130 /* Compute revents values for file handle H. If some events cannot happen
131 for the handle, eliminate them from *P_SOUGHT. */
134 windows_compute_revents (HANDLE h, int *p_sought)
136 int i, ret, happened;
137 INPUT_RECORD *irbuffer;
138 DWORD avail, nbuffer;
140 IO_STATUS_BLOCK iosb;
141 FILE_PIPE_LOCAL_INFORMATION fpli;
142 static PNtQueryInformationFile NtQueryInformationFile;
143 static BOOL once_only;
145 switch (GetFileType (h))
150 NtQueryInformationFile = (PNtQueryInformationFile)
151 GetProcAddress (GetModuleHandle ("ntdll.dll"),
152 "NtQueryInformationFile");
157 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
160 happened |= *p_sought & (POLLIN | POLLRDNORM);
162 else if (GetLastError () == ERROR_BROKEN_PIPE)
167 /* It was the write-end of the pipe. Check if it is writable.
168 If NtQueryInformationFile fails, optimistically assume the pipe is
169 writable. This could happen on Windows 9x, where
170 NtQueryInformationFile is not available, or if we inherit a pipe
171 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
172 (I think this should not happen since Windows XP SP2; WINE seems
173 fine too). Otherwise, ensure that enough space is available for
175 memset (&iosb, 0, sizeof (iosb));
176 memset (&fpli, 0, sizeof (fpli));
178 if (!NtQueryInformationFile
179 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
180 FilePipeLocalInformation)
181 || fpli.WriteQuotaAvailable >= PIPE_BUF
182 || (fpli.OutboundQuota < PIPE_BUF &&
183 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
184 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
189 ret = WaitForSingleObject (h, 0);
190 if (!IsConsoleHandle (h))
191 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
194 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
198 *p_sought &= POLLIN | POLLRDNORM;
204 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
205 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
206 if (!bRet || avail == 0)
209 for (i = 0; i < avail; i++)
210 if (irbuffer[i].EventType == KEY_EVENT)
217 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
222 ret = WaitForSingleObject (h, 0);
223 if (ret == WAIT_OBJECT_0)
224 return *p_sought & ~(POLLPRI | POLLRDBAND);
226 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
230 /* Convert fd_sets returned by select into revents values. */
233 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
237 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
238 happened |= (POLLIN | POLLRDNORM) & sought;
240 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
246 r = recv (h, data, sizeof (data), MSG_PEEK);
247 error = WSAGetLastError ();
250 if (r > 0 || error == WSAENOTCONN)
251 happened |= (POLLIN | POLLRDNORM) & sought;
253 /* Distinguish hung-up sockets from other errors. */
254 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
255 || error == WSAECONNABORTED || error == WSAENETRESET)
262 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
263 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
265 if (lNetworkEvents & FD_OOB)
266 happened |= (POLLPRI | POLLRDBAND) & sought;
273 /* Convert select(2) returned fd_sets into poll(2) revents values. */
275 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
278 if (FD_ISSET (fd, rfds))
283 # if defined __MACH__ && defined __APPLE__
284 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
285 for some kinds of descriptors. Detect if this descriptor is a
286 connected socket, a server socket, or something else using a
287 0-byte recv, and use ioctl(2) to detect POLLHUP. */
288 r = recv (fd, NULL, 0, MSG_PEEK);
289 socket_errno = (r < 0) ? errno : 0;
290 if (r == 0 || socket_errno == ENOTSOCK)
291 ioctl (fd, FIONREAD, &r);
294 r = recv (fd, data, sizeof (data), MSG_PEEK);
295 socket_errno = (r < 0) ? errno : 0;
300 /* If the event happened on an unconnected server socket,
302 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
303 happened |= (POLLIN | POLLRDNORM) & sought;
305 /* Distinguish hung-up sockets from other errors. */
306 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
307 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
310 /* some systems can't use recv() on non-socket, including HP NonStop */
311 else if (socket_errno == ENOTSOCK)
312 happened |= (POLLIN | POLLRDNORM) & sought;
318 if (FD_ISSET (fd, wfds))
319 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
321 if (FD_ISSET (fd, efds))
322 happened |= (POLLPRI | POLLRDBAND) & sought;
329 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
331 #ifndef WINDOWS_NATIVE
332 fd_set rfds, wfds, efds;
343 /* Don't check directly for NFD too large. Any practical use of a
344 too-large NFD is caught by one of the other checks below, and
345 checking directly for getdtablesize is too much of a portability
346 and/or performance and/or correctness hassle. */
348 /* EFAULT is not necessary to implement, but let's do it in the
356 /* convert timeout number into a timeval structure */
363 else if (timeout > 0)
366 ptv->tv_sec = timeout / 1000;
367 ptv->tv_usec = (timeout % 1000) * 1000;
369 else if (timeout == INFTIM)
378 /* create fd sets and determine max fd */
383 for (i = 0; i < nfd; i++)
387 if (maxfd < pfd[i].fd)
390 if (FD_SETSIZE <= maxfd)
396 if (pfd[i].events & (POLLIN | POLLRDNORM))
397 FD_SET (pfd[i].fd, &rfds);
398 /* see select(2): "the only exceptional condition detectable
399 is out-of-band data received on a socket", hence we push
400 POLLWRBAND events onto wfds instead of efds. */
401 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
402 FD_SET (pfd[i].fd, &wfds);
403 if (pfd[i].events & (POLLPRI | POLLRDBAND))
404 FD_SET (pfd[i].fd, &efds);
407 /* examine fd sets */
408 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
412 /* establish results */
414 for (i = 0; i < nfd; i++)
416 pfd[i].revents = (pfd[i].fd < 0
418 : compute_revents (pfd[i].fd, pfd[i].events,
419 &rfds, &wfds, &efds));
420 rc += pfd[i].revents != 0;
425 static struct timeval tv0;
426 static HANDLE hEvent;
428 HANDLE h, handle_array[FD_SETSIZE + 2];
429 DWORD ret, wait_timeout, nhandles;
430 fd_set rfds, wfds, xfds;
436 if (nfd < 0 || timeout < -1)
443 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
446 handle_array[0] = hEvent;
452 /* Classify socket handles and create fd sets. */
453 for (i = 0; i < nfd; i++)
455 int sought = pfd[i].events;
459 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
460 | POLLPRI | POLLRDBAND)))
463 h = (HANDLE) _get_osfhandle (pfd[i].fd);
465 if (IsSocketHandle (h))
467 int requested = FD_CLOSE;
469 /* see above; socket handles are mapped onto select. */
470 if (sought & (POLLIN | POLLRDNORM))
472 requested |= FD_READ | FD_ACCEPT;
473 FD_SET ((SOCKET) h, &rfds);
475 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
477 requested |= FD_WRITE | FD_CONNECT;
478 FD_SET ((SOCKET) h, &wfds);
480 if (sought & (POLLPRI | POLLRDBAND))
483 FD_SET ((SOCKET) h, &xfds);
487 WSAEventSelect ((SOCKET) h, hEvent, requested);
491 /* Poll now. If we get an event, do not poll again. Also,
492 screen buffer handles are waitable, and they'll block until
493 a character is available. windows_compute_revents eliminates
494 bits for the "wrong" direction. */
495 pfd[i].revents = windows_compute_revents (h, &sought);
497 handle_array[nhandles++] = h;
503 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
505 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
506 no need to call select again. */
513 if (timeout == INFTIM)
514 wait_timeout = INFINITE;
516 wait_timeout = timeout;
521 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
522 wait_timeout, QS_ALLINPUT);
524 if (ret == WAIT_OBJECT_0 + nhandles)
526 /* new input of some other kind */
528 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
530 TranslateMessage (&msg);
531 DispatchMessage (&msg);
539 select (0, &rfds, &wfds, &xfds, &tv0);
541 /* Place a sentinel at the end of the array. */
542 handle_array[nhandles] = NULL;
544 for (i = 0; i < nfd; i++)
550 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
551 POLLOUT | POLLWRNORM | POLLWRBAND)))
554 h = (HANDLE) _get_osfhandle (pfd[i].fd);
555 if (h != handle_array[nhandles])
558 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
559 WSAEventSelect ((SOCKET) h, 0, 0);
561 /* If we're lucky, WSAEnumNetworkEvents already provided a way
562 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
563 if (FD_ISSET ((SOCKET) h, &rfds)
564 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
565 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
566 if (FD_ISSET ((SOCKET) h, &wfds))
567 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
568 if (FD_ISSET ((SOCKET) h, &xfds))
569 ev.lNetworkEvents |= FD_OOB;
571 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
577 int sought = pfd[i].events;
578 happened = windows_compute_revents (h, &sought);
582 if ((pfd[i].revents |= happened) != 0)
586 if (!rc && timeout == INFTIM)