1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2013 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>
38 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
39 # define WINDOWS_NATIVE
40 # include <winsock2.h>
45 # include "msvc-nothrow.h"
47 # include <sys/time.h>
48 # include <sys/socket.h>
49 # include <sys/select.h>
53 #ifdef HAVE_SYS_IOCTL_H
54 # include <sys/ioctl.h>
56 #ifdef HAVE_SYS_FILIO_H
57 # include <sys/filio.h>
66 /* BeOS does not have MSG_PEEK. */
73 /* Optimized test whether a HANDLE refers to a console.
74 See <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00065.html>. */
75 #define IsConsoleHandle(h) (((intptr_t) (h) & 3) == 3)
78 IsSocketHandle (HANDLE h)
82 if (IsConsoleHandle (h))
85 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
86 WSAEnumNetworkEvents instead distinguishes the two correctly. */
87 ev.lNetworkEvents = 0xDEADBEEF;
88 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
89 return ev.lNetworkEvents != 0xDEADBEEF;
92 /* Declare data structures for ntdll functions. */
93 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
95 ULONG NamedPipeConfiguration;
96 ULONG MaximumInstances;
97 ULONG CurrentInstances;
99 ULONG ReadDataAvailable;
101 ULONG WriteQuotaAvailable;
102 ULONG NamedPipeState;
104 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
106 typedef struct _IO_STATUS_BLOCK
112 ULONG_PTR Information;
113 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
115 typedef enum _FILE_INFORMATION_CLASS {
116 FilePipeLocalInformation = 24
117 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
119 typedef DWORD (WINAPI *PNtQueryInformationFile)
120 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
123 # define PIPE_BUF 512
126 /* Compute revents values for file handle H. If some events cannot happen
127 for the handle, eliminate them from *P_SOUGHT. */
130 windows_compute_revents (HANDLE h, int *p_sought)
132 int i, ret, happened;
133 INPUT_RECORD *irbuffer;
134 DWORD avail, nbuffer;
136 IO_STATUS_BLOCK iosb;
137 FILE_PIPE_LOCAL_INFORMATION fpli;
138 static PNtQueryInformationFile NtQueryInformationFile;
139 static BOOL once_only;
141 switch (GetFileType (h))
146 NtQueryInformationFile = (PNtQueryInformationFile)
147 GetProcAddress (GetModuleHandle ("ntdll.dll"),
148 "NtQueryInformationFile");
153 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
156 happened |= *p_sought & (POLLIN | POLLRDNORM);
158 else if (GetLastError () == ERROR_BROKEN_PIPE)
163 /* It was the write-end of the pipe. Check if it is writable.
164 If NtQueryInformationFile fails, optimistically assume the pipe is
165 writable. This could happen on Windows 9x, where
166 NtQueryInformationFile is not available, or if we inherit a pipe
167 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
168 (I think this should not happen since Windows XP SP2; WINE seems
169 fine too). Otherwise, ensure that enough space is available for
171 memset (&iosb, 0, sizeof (iosb));
172 memset (&fpli, 0, sizeof (fpli));
174 if (!NtQueryInformationFile
175 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
176 FilePipeLocalInformation)
177 || fpli.WriteQuotaAvailable >= PIPE_BUF
178 || (fpli.OutboundQuota < PIPE_BUF &&
179 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
180 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
185 ret = WaitForSingleObject (h, 0);
186 if (!IsConsoleHandle (h))
187 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
190 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
194 *p_sought &= POLLIN | POLLRDNORM;
200 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
201 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
202 if (!bRet || avail == 0)
205 for (i = 0; i < avail; i++)
206 if (irbuffer[i].EventType == KEY_EVENT)
213 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
218 ret = WaitForSingleObject (h, 0);
219 if (ret == WAIT_OBJECT_0)
220 return *p_sought & ~(POLLPRI | POLLRDBAND);
222 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
226 /* Convert fd_sets returned by select into revents values. */
229 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
233 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
234 happened |= (POLLIN | POLLRDNORM) & sought;
236 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
242 r = recv (h, data, sizeof (data), MSG_PEEK);
243 error = WSAGetLastError ();
246 if (r > 0 || error == WSAENOTCONN)
247 happened |= (POLLIN | POLLRDNORM) & sought;
249 /* Distinguish hung-up sockets from other errors. */
250 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
251 || error == WSAECONNABORTED || error == WSAENETRESET)
258 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
259 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
261 if (lNetworkEvents & FD_OOB)
262 happened |= (POLLPRI | POLLRDBAND) & sought;
269 /* Convert select(2) returned fd_sets into poll(2) revents values. */
271 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
274 if (FD_ISSET (fd, rfds))
279 # if defined __MACH__ && defined __APPLE__
280 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
281 for some kinds of descriptors. Detect if this descriptor is a
282 connected socket, a server socket, or something else using a
283 0-byte recv, and use ioctl(2) to detect POLLHUP. */
284 r = recv (fd, NULL, 0, MSG_PEEK);
285 socket_errno = (r < 0) ? errno : 0;
286 if (r == 0 || socket_errno == ENOTSOCK)
287 ioctl (fd, FIONREAD, &r);
290 r = recv (fd, data, sizeof (data), MSG_PEEK);
291 socket_errno = (r < 0) ? errno : 0;
296 /* If the event happened on an unconnected server socket,
298 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
299 happened |= (POLLIN | POLLRDNORM) & sought;
301 /* Distinguish hung-up sockets from other errors. */
302 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
303 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
306 /* some systems can't use recv() on non-socket, including HP NonStop */
307 else if (socket_errno == ENOTSOCK)
308 happened |= (POLLIN | POLLRDNORM) & sought;
314 if (FD_ISSET (fd, wfds))
315 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
317 if (FD_ISSET (fd, efds))
318 happened |= (POLLPRI | POLLRDBAND) & sought;
325 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
327 #ifndef WINDOWS_NATIVE
328 fd_set rfds, wfds, efds;
335 static int sc_open_max = -1;
338 || (nfd > sc_open_max
339 && (sc_open_max != -1
340 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
345 # else /* !_SC_OPEN_MAX */
347 if (nfd < 0 || nfd > OPEN_MAX)
352 # endif /* OPEN_MAX -- else, no check is needed */
353 # endif /* !_SC_OPEN_MAX */
355 /* EFAULT is not necessary to implement, but let's do it in the
363 /* convert timeout number into a timeval structure */
370 else if (timeout > 0)
373 ptv->tv_sec = timeout / 1000;
374 ptv->tv_usec = (timeout % 1000) * 1000;
376 else if (timeout == INFTIM)
385 /* create fd sets and determine max fd */
390 for (i = 0; i < nfd; i++)
395 if (pfd[i].events & (POLLIN | POLLRDNORM))
396 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);
405 if (pfd[i].fd >= maxfd
406 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
407 | POLLRDNORM | POLLRDBAND
408 | POLLWRNORM | POLLWRBAND)))
411 if (maxfd > FD_SETSIZE)
419 /* examine fd sets */
420 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
424 /* establish results */
426 for (i = 0; i < nfd; i++)
431 int happened = compute_revents (pfd[i].fd, pfd[i].events,
432 &rfds, &wfds, &efds);
435 pfd[i].revents = happened;
442 static struct timeval tv0;
443 static HANDLE hEvent;
445 HANDLE h, handle_array[FD_SETSIZE + 2];
446 DWORD ret, wait_timeout, nhandles;
447 fd_set rfds, wfds, xfds;
453 if (nfd < 0 || timeout < -1)
460 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
463 handle_array[0] = hEvent;
469 /* Classify socket handles and create fd sets. */
470 for (i = 0; i < nfd; i++)
472 int sought = pfd[i].events;
476 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
477 | POLLPRI | POLLRDBAND)))
480 h = (HANDLE) _get_osfhandle (pfd[i].fd);
482 if (IsSocketHandle (h))
484 int requested = FD_CLOSE;
486 /* see above; socket handles are mapped onto select. */
487 if (sought & (POLLIN | POLLRDNORM))
489 requested |= FD_READ | FD_ACCEPT;
490 FD_SET ((SOCKET) h, &rfds);
492 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
494 requested |= FD_WRITE | FD_CONNECT;
495 FD_SET ((SOCKET) h, &wfds);
497 if (sought & (POLLPRI | POLLRDBAND))
500 FD_SET ((SOCKET) h, &xfds);
504 WSAEventSelect ((SOCKET) h, hEvent, requested);
508 /* Poll now. If we get an event, do not poll again. Also,
509 screen buffer handles are waitable, and they'll block until
510 a character is available. windows_compute_revents eliminates
511 bits for the "wrong" direction. */
512 pfd[i].revents = windows_compute_revents (h, &sought);
514 handle_array[nhandles++] = h;
520 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
522 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
523 no need to call select again. */
530 if (timeout == INFTIM)
531 wait_timeout = INFINITE;
533 wait_timeout = timeout;
538 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
539 wait_timeout, QS_ALLINPUT);
541 if (ret == WAIT_OBJECT_0 + nhandles)
543 /* new input of some other kind */
545 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
547 TranslateMessage (&msg);
548 DispatchMessage (&msg);
556 select (0, &rfds, &wfds, &xfds, &tv0);
558 /* Place a sentinel at the end of the array. */
559 handle_array[nhandles] = NULL;
561 for (i = 0; i < nfd; i++)
567 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
568 POLLOUT | POLLWRNORM | POLLWRBAND)))
571 h = (HANDLE) _get_osfhandle (pfd[i].fd);
572 if (h != handle_array[nhandles])
575 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
576 WSAEventSelect ((SOCKET) h, 0, 0);
578 /* If we're lucky, WSAEnumNetworkEvents already provided a way
579 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
580 if (FD_ISSET ((SOCKET) h, &rfds)
581 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
582 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
583 if (FD_ISSET ((SOCKET) h, &wfds))
584 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
585 if (FD_ISSET ((SOCKET) h, &xfds))
586 ev.lNetworkEvents |= FD_OOB;
588 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
594 int sought = pfd[i].events;
595 happened = windows_compute_revents (h, &sought);
599 if ((pfd[i].revents |= happened) != 0)
603 if (!rc && timeout == INFTIM)