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) (((intptr_t) (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 Windows 9x, where
167 NtQueryInformationFile is not available, or if we inherit a pipe
168 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
169 (I think this should not happen since Windows XP SP2; WINE seems
170 fine too). Otherwise, ensure that enough space is available for
172 memset (&iosb, 0, sizeof (iosb));
173 memset (&fpli, 0, sizeof (fpli));
175 if (!NtQueryInformationFile
176 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
177 FilePipeLocalInformation)
178 || fpli.WriteQuotaAvailable >= PIPE_BUF
179 || (fpli.OutboundQuota < PIPE_BUF &&
180 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
181 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
186 ret = WaitForSingleObject (h, 0);
187 if (!IsConsoleHandle (h))
188 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
191 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
195 *p_sought &= POLLIN | POLLRDNORM;
201 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
202 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
203 if (!bRet || avail == 0)
206 for (i = 0; i < avail; i++)
207 if (irbuffer[i].EventType == KEY_EVENT)
214 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
219 ret = WaitForSingleObject (h, 0);
220 if (ret == WAIT_OBJECT_0)
221 return *p_sought & ~(POLLPRI | POLLRDBAND);
223 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
227 /* Convert fd_sets returned by select into revents values. */
230 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
234 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
235 happened |= (POLLIN | POLLRDNORM) & sought;
237 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
243 r = recv (h, data, sizeof (data), MSG_PEEK);
244 error = WSAGetLastError ();
247 if (r > 0 || error == WSAENOTCONN)
248 happened |= (POLLIN | POLLRDNORM) & sought;
250 /* Distinguish hung-up sockets from other errors. */
251 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
252 || error == WSAECONNABORTED || error == WSAENETRESET)
259 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
260 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
262 if (lNetworkEvents & FD_OOB)
263 happened |= (POLLPRI | POLLRDBAND) & sought;
270 /* Convert select(2) returned fd_sets into poll(2) revents values. */
272 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
275 if (FD_ISSET (fd, rfds))
280 # if defined __MACH__ && defined __APPLE__
281 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
282 for some kinds of descriptors. Detect if this descriptor is a
283 connected socket, a server socket, or something else using a
284 0-byte recv, and use ioctl(2) to detect POLLHUP. */
285 r = recv (fd, NULL, 0, MSG_PEEK);
286 socket_errno = (r < 0) ? errno : 0;
287 if (r == 0 || socket_errno == ENOTSOCK)
288 ioctl (fd, FIONREAD, &r);
291 r = recv (fd, data, sizeof (data), MSG_PEEK);
292 socket_errno = (r < 0) ? errno : 0;
297 /* If the event happened on an unconnected server socket,
299 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
300 happened |= (POLLIN | POLLRDNORM) & sought;
302 /* Distinguish hung-up sockets from other errors. */
303 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
304 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
311 if (FD_ISSET (fd, wfds))
312 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
314 if (FD_ISSET (fd, efds))
315 happened |= (POLLPRI | POLLRDBAND) & sought;
322 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
324 #ifndef WINDOWS_NATIVE
325 fd_set rfds, wfds, efds;
332 static int sc_open_max = -1;
335 || (nfd > sc_open_max
336 && (sc_open_max != -1
337 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
342 # else /* !_SC_OPEN_MAX */
344 if (nfd < 0 || nfd > OPEN_MAX)
349 # endif /* OPEN_MAX -- else, no check is needed */
350 # endif /* !_SC_OPEN_MAX */
352 /* EFAULT is not necessary to implement, but let's do it in the
360 /* convert timeout number into a timeval structure */
367 else if (timeout > 0)
370 ptv->tv_sec = timeout / 1000;
371 ptv->tv_usec = (timeout % 1000) * 1000;
373 else if (timeout == INFTIM)
382 /* create fd sets and determine max fd */
387 for (i = 0; i < nfd; i++)
392 if (pfd[i].events & (POLLIN | POLLRDNORM))
393 FD_SET (pfd[i].fd, &rfds);
395 /* see select(2): "the only exceptional condition detectable
396 is out-of-band data received on a socket", hence we push
397 POLLWRBAND events onto wfds instead of efds. */
398 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
399 FD_SET (pfd[i].fd, &wfds);
400 if (pfd[i].events & (POLLPRI | POLLRDBAND))
401 FD_SET (pfd[i].fd, &efds);
402 if (pfd[i].fd >= maxfd
403 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
404 | POLLRDNORM | POLLRDBAND
405 | POLLWRNORM | POLLWRBAND)))
408 if (maxfd > FD_SETSIZE)
416 /* examine fd sets */
417 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
421 /* establish results */
423 for (i = 0; i < nfd; i++)
428 int happened = compute_revents (pfd[i].fd, pfd[i].events,
429 &rfds, &wfds, &efds);
432 pfd[i].revents = happened;
439 static struct timeval tv0;
440 static HANDLE hEvent;
442 HANDLE h, handle_array[FD_SETSIZE + 2];
443 DWORD ret, wait_timeout, nhandles;
444 fd_set rfds, wfds, xfds;
450 if (nfd < 0 || timeout < -1)
457 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
460 handle_array[0] = hEvent;
466 /* Classify socket handles and create fd sets. */
467 for (i = 0; i < nfd; i++)
469 int sought = pfd[i].events;
473 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
474 | POLLPRI | POLLRDBAND)))
477 h = (HANDLE) _get_osfhandle (pfd[i].fd);
479 if (IsSocketHandle (h))
481 int requested = FD_CLOSE;
483 /* see above; socket handles are mapped onto select. */
484 if (sought & (POLLIN | POLLRDNORM))
486 requested |= FD_READ | FD_ACCEPT;
487 FD_SET ((SOCKET) h, &rfds);
489 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
491 requested |= FD_WRITE | FD_CONNECT;
492 FD_SET ((SOCKET) h, &wfds);
494 if (sought & (POLLPRI | POLLRDBAND))
497 FD_SET ((SOCKET) h, &xfds);
501 WSAEventSelect ((SOCKET) h, hEvent, requested);
505 /* Poll now. If we get an event, do not poll again. Also,
506 screen buffer handles are waitable, and they'll block until
507 a character is available. windows_compute_revents eliminates
508 bits for the "wrong" direction. */
509 pfd[i].revents = windows_compute_revents (h, &sought);
511 handle_array[nhandles++] = h;
517 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
519 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
520 no need to call select again. */
527 if (timeout == INFTIM)
528 wait_timeout = INFINITE;
530 wait_timeout = timeout;
535 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
536 wait_timeout, QS_ALLINPUT);
538 if (ret == WAIT_OBJECT_0 + nhandles)
540 /* new input of some other kind */
542 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
544 TranslateMessage (&msg);
545 DispatchMessage (&msg);
553 select (0, &rfds, &wfds, &xfds, &tv0);
555 /* Place a sentinel at the end of the array. */
556 handle_array[nhandles] = NULL;
558 for (i = 0; i < nfd; i++)
564 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
565 POLLOUT | POLLWRNORM | POLLWRBAND)))
568 h = (HANDLE) _get_osfhandle (pfd[i].fd);
569 if (h != handle_array[nhandles])
572 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
573 WSAEventSelect ((SOCKET) h, 0, 0);
575 /* If we're lucky, WSAEnumNetworkEvents already provided a way
576 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
577 if (FD_ISSET ((SOCKET) h, &rfds)
578 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
579 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
580 if (FD_ISSET ((SOCKET) h, &wfds))
581 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
582 if (FD_ISSET ((SOCKET) h, &xfds))
583 ev.lNetworkEvents |= FD_OOB;
585 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
591 int sought = pfd[i].events;
592 happened = windows_compute_revents (h, &sought);
596 if ((pfd[i].revents |= happened) != 0)
600 if (!rc && timeout == INFTIM)