1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2011 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__
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 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
77 IsSocketHandle (HANDLE h)
81 if (IsConsoleHandle (h))
84 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
85 WSAEnumNetworkEvents instead distinguishes the two correctly. */
86 ev.lNetworkEvents = 0xDEADBEEF;
87 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
88 return ev.lNetworkEvents != 0xDEADBEEF;
91 /* Declare data structures for ntdll functions. */
92 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
94 ULONG NamedPipeConfiguration;
95 ULONG MaximumInstances;
96 ULONG CurrentInstances;
98 ULONG ReadDataAvailable;
100 ULONG WriteQuotaAvailable;
101 ULONG NamedPipeState;
103 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
105 typedef struct _IO_STATUS_BLOCK
111 ULONG_PTR Information;
112 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
114 typedef enum _FILE_INFORMATION_CLASS {
115 FilePipeLocalInformation = 24
116 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
118 typedef DWORD (WINAPI *PNtQueryInformationFile)
119 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
122 # define PIPE_BUF 512
125 /* Compute revents values for file handle H. If some events cannot happen
126 for the handle, eliminate them from *P_SOUGHT. */
129 win32_compute_revents (HANDLE h, int *p_sought)
131 int i, ret, happened;
132 INPUT_RECORD *irbuffer;
133 DWORD avail, nbuffer;
135 IO_STATUS_BLOCK iosb;
136 FILE_PIPE_LOCAL_INFORMATION fpli;
137 static PNtQueryInformationFile NtQueryInformationFile;
138 static BOOL once_only;
140 switch (GetFileType (h))
145 NtQueryInformationFile = (PNtQueryInformationFile)
146 GetProcAddress (GetModuleHandle ("ntdll.dll"),
147 "NtQueryInformationFile");
152 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
155 happened |= *p_sought & (POLLIN | POLLRDNORM);
157 else if (GetLastError () == ERROR_BROKEN_PIPE)
162 /* It was the write-end of the pipe. Check if it is writable.
163 If NtQueryInformationFile fails, optimistically assume the pipe is
164 writable. This could happen on Win9x, where NtQueryInformationFile
165 is not available, or if we inherit a pipe that doesn't permit
166 FILE_READ_ATTRIBUTES access on the write end (I think this should
167 not happen since WinXP SP2; WINE seems fine too). Otherwise,
168 ensure that enough space is available for atomic writes. */
169 memset (&iosb, 0, sizeof (iosb));
170 memset (&fpli, 0, sizeof (fpli));
172 if (!NtQueryInformationFile
173 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
174 FilePipeLocalInformation)
175 || fpli.WriteQuotaAvailable >= PIPE_BUF
176 || (fpli.OutboundQuota < PIPE_BUF &&
177 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
178 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
183 ret = WaitForSingleObject (h, 0);
184 if (!IsConsoleHandle (h))
185 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
188 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
192 *p_sought &= POLLIN | POLLRDNORM;
198 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
199 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
200 if (!bRet || avail == 0)
203 for (i = 0; i < avail; i++)
204 if (irbuffer[i].EventType == KEY_EVENT)
211 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
216 ret = WaitForSingleObject (h, 0);
217 if (ret == WAIT_OBJECT_0)
218 return *p_sought & ~(POLLPRI | POLLRDBAND);
220 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
224 /* Convert fd_sets returned by select into revents values. */
227 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
231 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
232 happened |= (POLLIN | POLLRDNORM) & sought;
234 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
240 r = recv (h, data, sizeof (data), MSG_PEEK);
241 error = WSAGetLastError ();
244 if (r > 0 || error == WSAENOTCONN)
245 happened |= (POLLIN | POLLRDNORM) & sought;
247 /* Distinguish hung-up sockets from other errors. */
248 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
249 || error == WSAECONNABORTED || error == WSAENETRESET)
256 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
257 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
259 if (lNetworkEvents & FD_OOB)
260 happened |= (POLLPRI | POLLRDBAND) & sought;
267 /* Convert select(2) returned fd_sets into poll(2) revents values. */
269 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
272 if (FD_ISSET (fd, rfds))
277 # if defined __MACH__ && defined __APPLE__
278 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
279 for some kinds of descriptors. Detect if this descriptor is a
280 connected socket, a server socket, or something else using a
281 0-byte recv, and use ioctl(2) to detect POLLHUP. */
282 r = recv (fd, NULL, 0, MSG_PEEK);
283 socket_errno = (r < 0) ? errno : 0;
284 if (r == 0 || socket_errno == ENOTSOCK)
285 ioctl (fd, FIONREAD, &r);
288 r = recv (fd, data, sizeof (data), MSG_PEEK);
289 socket_errno = (r < 0) ? errno : 0;
294 /* If the event happened on an unconnected server socket,
296 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
297 happened |= (POLLIN | POLLRDNORM) & sought;
299 /* Distinguish hung-up sockets from other errors. */
300 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
301 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
308 if (FD_ISSET (fd, wfds))
309 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
311 if (FD_ISSET (fd, efds))
312 happened |= (POLLPRI | POLLRDBAND) & sought;
319 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
322 fd_set rfds, wfds, efds;
329 static int sc_open_max = -1;
332 || (nfd > sc_open_max
333 && (sc_open_max != -1
334 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
339 # else /* !_SC_OPEN_MAX */
341 if (nfd < 0 || nfd > OPEN_MAX)
346 # endif /* OPEN_MAX -- else, no check is needed */
347 # endif /* !_SC_OPEN_MAX */
349 /* EFAULT is not necessary to implement, but let's do it in the
357 /* convert timeout number into a timeval structure */
364 else if (timeout > 0)
367 ptv->tv_sec = timeout / 1000;
368 ptv->tv_usec = (timeout % 1000) * 1000;
370 else if (timeout == INFTIM)
379 /* create fd sets and determine max fd */
384 for (i = 0; i < nfd; i++)
389 if (pfd[i].events & (POLLIN | POLLRDNORM))
390 FD_SET (pfd[i].fd, &rfds);
392 /* see select(2): "the only exceptional condition detectable
393 is out-of-band data received on a socket", hence we push
394 POLLWRBAND events onto wfds instead of efds. */
395 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
396 FD_SET (pfd[i].fd, &wfds);
397 if (pfd[i].events & (POLLPRI | POLLRDBAND))
398 FD_SET (pfd[i].fd, &efds);
399 if (pfd[i].fd >= maxfd
400 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
401 | POLLRDNORM | POLLRDBAND
402 | POLLWRNORM | POLLWRBAND)))
405 if (maxfd > FD_SETSIZE)
413 /* examine fd sets */
414 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
418 /* establish results */
420 for (i = 0; i < nfd; i++)
425 int happened = compute_revents (pfd[i].fd, pfd[i].events,
426 &rfds, &wfds, &efds);
429 pfd[i].revents = happened;
436 static struct timeval tv0;
437 static HANDLE hEvent;
439 HANDLE h, handle_array[FD_SETSIZE + 2];
440 DWORD ret, wait_timeout, nhandles;
441 fd_set rfds, wfds, xfds;
447 if (nfd < 0 || timeout < -1)
454 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
457 handle_array[0] = hEvent;
463 /* Classify socket handles and create fd sets. */
464 for (i = 0; i < nfd; i++)
466 int sought = pfd[i].events;
470 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
471 | POLLPRI | POLLRDBAND)))
474 h = (HANDLE) _get_osfhandle (pfd[i].fd);
476 if (IsSocketHandle (h))
478 int requested = FD_CLOSE;
480 /* see above; socket handles are mapped onto select. */
481 if (sought & (POLLIN | POLLRDNORM))
483 requested |= FD_READ | FD_ACCEPT;
484 FD_SET ((SOCKET) h, &rfds);
486 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
488 requested |= FD_WRITE | FD_CONNECT;
489 FD_SET ((SOCKET) h, &wfds);
491 if (sought & (POLLPRI | POLLRDBAND))
494 FD_SET ((SOCKET) h, &xfds);
498 WSAEventSelect ((SOCKET) h, hEvent, requested);
502 /* Poll now. If we get an event, do not poll again. Also,
503 screen buffer handles are waitable, and they'll block until
504 a character is available. win32_compute_revents eliminates
505 bits for the "wrong" direction. */
506 pfd[i].revents = win32_compute_revents (h, &sought);
508 handle_array[nhandles++] = h;
514 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
516 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
517 no need to call select again. */
524 if (timeout == INFTIM)
525 wait_timeout = INFINITE;
527 wait_timeout = timeout;
532 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
533 wait_timeout, QS_ALLINPUT);
535 if (ret == WAIT_OBJECT_0 + nhandles)
537 /* new input of some other kind */
539 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
541 TranslateMessage (&msg);
542 DispatchMessage (&msg);
550 select (0, &rfds, &wfds, &xfds, &tv0);
552 /* Place a sentinel at the end of the array. */
553 handle_array[nhandles] = NULL;
555 for (i = 0; i < nfd; i++)
561 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
562 POLLOUT | POLLWRNORM | POLLWRBAND)))
565 h = (HANDLE) _get_osfhandle (pfd[i].fd);
566 if (h != handle_array[nhandles])
569 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
570 WSAEventSelect ((SOCKET) h, 0, 0);
572 /* If we're lucky, WSAEnumNetworkEvents already provided a way
573 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
574 if (FD_ISSET ((SOCKET) h, &rfds)
575 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
576 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
577 if (FD_ISSET ((SOCKET) h, &wfds))
578 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
579 if (FD_ISSET ((SOCKET) h, &xfds))
580 ev.lNetworkEvents |= FD_OOB;
582 happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
588 int sought = pfd[i].events;
589 happened = win32_compute_revents (h, &sought);
593 if ((pfd[i].revents |= happened) != 0)
597 if (!rc && timeout == INFTIM)