1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2012 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, write to the Free Software Foundation,
20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
22 /* Tell gcc not to warn about the (nfd < 0) tests, below. */
23 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
24 # pragma GCC diagnostic ignored "-Wtype-limits"
30 #include <sys/types.h>
39 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
40 # define WINDOWS_NATIVE
41 # include <winsock2.h>
46 # include "msvc-nothrow.h"
48 # include <sys/time.h>
49 # include <sys/socket.h>
50 # include <sys/select.h>
54 #ifdef HAVE_SYS_IOCTL_H
55 # include <sys/ioctl.h>
57 #ifdef HAVE_SYS_FILIO_H
58 # include <sys/filio.h>
67 /* BeOS does not have MSG_PEEK. */
74 /* Optimized test whether a HANDLE refers to a console.
75 See <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00065.html>. */
76 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
79 IsSocketHandle (HANDLE h)
83 if (IsConsoleHandle (h))
86 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
87 WSAEnumNetworkEvents instead distinguishes the two correctly. */
88 ev.lNetworkEvents = 0xDEADBEEF;
89 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
90 return ev.lNetworkEvents != 0xDEADBEEF;
93 /* Declare data structures for ntdll functions. */
94 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
96 ULONG NamedPipeConfiguration;
97 ULONG MaximumInstances;
98 ULONG CurrentInstances;
100 ULONG ReadDataAvailable;
102 ULONG WriteQuotaAvailable;
103 ULONG NamedPipeState;
105 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
107 typedef struct _IO_STATUS_BLOCK
113 ULONG_PTR Information;
114 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
116 typedef enum _FILE_INFORMATION_CLASS {
117 FilePipeLocalInformation = 24
118 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
120 typedef DWORD (WINAPI *PNtQueryInformationFile)
121 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
124 # define PIPE_BUF 512
127 /* Compute revents values for file handle H. If some events cannot happen
128 for the handle, eliminate them from *P_SOUGHT. */
131 windows_compute_revents (HANDLE h, int *p_sought)
133 int i, ret, happened;
134 INPUT_RECORD *irbuffer;
135 DWORD avail, nbuffer;
137 IO_STATUS_BLOCK iosb;
138 FILE_PIPE_LOCAL_INFORMATION fpli;
139 static PNtQueryInformationFile NtQueryInformationFile;
140 static BOOL once_only;
142 switch (GetFileType (h))
147 NtQueryInformationFile = (PNtQueryInformationFile)
148 GetProcAddress (GetModuleHandle ("ntdll.dll"),
149 "NtQueryInformationFile");
154 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
157 happened |= *p_sought & (POLLIN | POLLRDNORM);
159 else if (GetLastError () == ERROR_BROKEN_PIPE)
164 /* It was the write-end of the pipe. Check if it is writable.
165 If NtQueryInformationFile fails, optimistically assume the pipe is
166 writable. This could happen on Win9x, where NtQueryInformationFile
167 is not available, or if we inherit a pipe that doesn't permit
168 FILE_READ_ATTRIBUTES access on the write end (I think this should
169 not happen since WinXP SP2; WINE seems fine too). Otherwise,
170 ensure that enough space is available for atomic writes. */
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)
310 if (FD_ISSET (fd, wfds))
311 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
313 if (FD_ISSET (fd, efds))
314 happened |= (POLLPRI | POLLRDBAND) & sought;
321 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
323 #ifndef WINDOWS_NATIVE
324 fd_set rfds, wfds, efds;
331 static int sc_open_max = -1;
334 || (nfd > sc_open_max
335 && (sc_open_max != -1
336 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
341 # else /* !_SC_OPEN_MAX */
343 if (nfd < 0 || nfd > OPEN_MAX)
348 # endif /* OPEN_MAX -- else, no check is needed */
349 # endif /* !_SC_OPEN_MAX */
351 /* EFAULT is not necessary to implement, but let's do it in the
359 /* convert timeout number into a timeval structure */
366 else if (timeout > 0)
369 ptv->tv_sec = timeout / 1000;
370 ptv->tv_usec = (timeout % 1000) * 1000;
372 else if (timeout == INFTIM)
381 /* create fd sets and determine max fd */
386 for (i = 0; i < nfd; i++)
391 if (pfd[i].events & (POLLIN | POLLRDNORM))
392 FD_SET (pfd[i].fd, &rfds);
394 /* see select(2): "the only exceptional condition detectable
395 is out-of-band data received on a socket", hence we push
396 POLLWRBAND events onto wfds instead of efds. */
397 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
398 FD_SET (pfd[i].fd, &wfds);
399 if (pfd[i].events & (POLLPRI | POLLRDBAND))
400 FD_SET (pfd[i].fd, &efds);
401 if (pfd[i].fd >= maxfd
402 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
403 | POLLRDNORM | POLLRDBAND
404 | POLLWRNORM | POLLWRBAND)))
407 if (maxfd > FD_SETSIZE)
415 /* examine fd sets */
416 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
420 /* establish results */
422 for (i = 0; i < nfd; i++)
427 int happened = compute_revents (pfd[i].fd, pfd[i].events,
428 &rfds, &wfds, &efds);
431 pfd[i].revents = happened;
438 static struct timeval tv0;
439 static HANDLE hEvent;
441 HANDLE h, handle_array[FD_SETSIZE + 2];
442 DWORD ret, wait_timeout, nhandles;
443 fd_set rfds, wfds, xfds;
449 if (nfd < 0 || timeout < -1)
456 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
459 handle_array[0] = hEvent;
465 /* Classify socket handles and create fd sets. */
466 for (i = 0; i < nfd; i++)
468 int sought = pfd[i].events;
472 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
473 | POLLPRI | POLLRDBAND)))
476 h = (HANDLE) _get_osfhandle (pfd[i].fd);
478 if (IsSocketHandle (h))
480 int requested = FD_CLOSE;
482 /* see above; socket handles are mapped onto select. */
483 if (sought & (POLLIN | POLLRDNORM))
485 requested |= FD_READ | FD_ACCEPT;
486 FD_SET ((SOCKET) h, &rfds);
488 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
490 requested |= FD_WRITE | FD_CONNECT;
491 FD_SET ((SOCKET) h, &wfds);
493 if (sought & (POLLPRI | POLLRDBAND))
496 FD_SET ((SOCKET) h, &xfds);
500 WSAEventSelect ((SOCKET) h, hEvent, requested);
504 /* Poll now. If we get an event, do not poll again. Also,
505 screen buffer handles are waitable, and they'll block until
506 a character is available. windows_compute_revents eliminates
507 bits for the "wrong" direction. */
508 pfd[i].revents = windows_compute_revents (h, &sought);
510 handle_array[nhandles++] = h;
516 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
518 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
519 no need to call select again. */
526 if (timeout == INFTIM)
527 wait_timeout = INFINITE;
529 wait_timeout = timeout;
534 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
535 wait_timeout, QS_ALLINPUT);
537 if (ret == WAIT_OBJECT_0 + nhandles)
539 /* new input of some other kind */
541 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
543 TranslateMessage (&msg);
544 DispatchMessage (&msg);
552 select (0, &rfds, &wfds, &xfds, &tv0);
554 /* Place a sentinel at the end of the array. */
555 handle_array[nhandles] = NULL;
557 for (i = 0; i < nfd; i++)
563 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
564 POLLOUT | POLLWRNORM | POLLWRBAND)))
567 h = (HANDLE) _get_osfhandle (pfd[i].fd);
568 if (h != handle_array[nhandles])
571 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
572 WSAEventSelect ((SOCKET) h, 0, 0);
574 /* If we're lucky, WSAEnumNetworkEvents already provided a way
575 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
576 if (FD_ISSET ((SOCKET) h, &rfds)
577 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
578 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
579 if (FD_ISSET ((SOCKET) h, &wfds))
580 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
581 if (FD_ISSET ((SOCKET) h, &xfds))
582 ev.lNetworkEvents |= FD_OOB;
584 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
590 int sought = pfd[i].events;
591 happened = windows_compute_revents (h, &sought);
595 if ((pfd[i].revents |= happened) != 0)
599 if (!rc && timeout == INFTIM)