1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2010 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>
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 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
76 IsSocketHandle (HANDLE h)
80 if (IsConsoleHandle (h))
83 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
84 WSAEnumNetworkEvents instead distinguishes the two correctly. */
85 ev.lNetworkEvents = 0xDEADBEEF;
86 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
87 return ev.lNetworkEvents != 0xDEADBEEF;
90 /* Declare data structures for ntdll functions. */
91 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
93 ULONG NamedPipeConfiguration;
94 ULONG MaximumInstances;
95 ULONG CurrentInstances;
97 ULONG ReadDataAvailable;
99 ULONG WriteQuotaAvailable;
100 ULONG NamedPipeState;
102 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
104 typedef struct _IO_STATUS_BLOCK
110 ULONG_PTR Information;
111 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
113 typedef enum _FILE_INFORMATION_CLASS {
114 FilePipeLocalInformation = 24
115 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
117 typedef DWORD (WINAPI *PNtQueryInformationFile)
118 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
121 # define PIPE_BUF 512
124 /* Compute revents values for file handle H. If some events cannot happen
125 for the handle, eliminate them from *P_SOUGHT. */
128 win32_compute_revents (HANDLE h, int *p_sought)
130 int i, ret, happened;
131 INPUT_RECORD *irbuffer;
132 DWORD avail, nbuffer;
134 IO_STATUS_BLOCK iosb;
135 FILE_PIPE_LOCAL_INFORMATION fpli;
136 static PNtQueryInformationFile NtQueryInformationFile;
137 static BOOL once_only;
139 switch (GetFileType (h))
144 NtQueryInformationFile = (PNtQueryInformationFile)
145 GetProcAddress (GetModuleHandle ("ntdll.dll"),
146 "NtQueryInformationFile");
151 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
154 happened |= *p_sought & (POLLIN | POLLRDNORM);
156 else if (GetLastError () == ERROR_BROKEN_PIPE)
161 /* It was the write-end of the pipe. Check if it is writable.
162 If NtQueryInformationFile fails, optimistically assume the pipe is
163 writable. This could happen on Win9x, where NtQueryInformationFile
164 is not available, or if we inherit a pipe that doesn't permit
165 FILE_READ_ATTRIBUTES access on the write end (I think this should
166 not happen since WinXP SP2; WINE seems fine too). Otherwise,
167 ensure that enough space is available for atomic writes. */
168 memset (&iosb, 0, sizeof (iosb));
169 memset (&fpli, 0, sizeof (fpli));
171 if (!NtQueryInformationFile
172 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
173 FilePipeLocalInformation)
174 || fpli.WriteQuotaAvailable >= PIPE_BUF
175 || (fpli.OutboundQuota < PIPE_BUF &&
176 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
177 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
182 ret = WaitForSingleObject (h, 0);
183 if (!IsConsoleHandle (h))
184 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
187 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
191 *p_sought &= POLLIN | POLLRDNORM;
197 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
198 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
199 if (!bRet || avail == 0)
202 for (i = 0; i < avail; i++)
203 if (irbuffer[i].EventType == KEY_EVENT)
210 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
215 ret = WaitForSingleObject (h, 0);
216 if (ret == WAIT_OBJECT_0)
217 return *p_sought & ~(POLLPRI | POLLRDBAND);
219 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
223 /* Convert fd_sets returned by select into revents values. */
226 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
230 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
231 happened |= (POLLIN | POLLRDNORM) & sought;
233 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
239 r = recv (h, data, sizeof (data), MSG_PEEK);
240 error = WSAGetLastError ();
243 if (r > 0 || error == WSAENOTCONN)
244 happened |= (POLLIN | POLLRDNORM) & sought;
246 /* Distinguish hung-up sockets from other errors. */
247 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
248 || error == WSAECONNABORTED || error == WSAENETRESET)
255 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
256 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
258 if (lNetworkEvents & FD_OOB)
259 happened |= (POLLPRI | POLLRDBAND) & sought;
266 /* Convert select(2) returned fd_sets into poll(2) revents values. */
268 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
271 if (FD_ISSET (fd, rfds))
276 # if defined __MACH__ && defined __APPLE__
277 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
278 for some kinds of descriptors. Detect if this descriptor is a
279 connected socket, a server socket, or something else using a
280 0-byte recv, and use ioctl(2) to detect POLLHUP. */
281 r = recv (fd, NULL, 0, MSG_PEEK);
282 socket_errno = (r < 0) ? errno : 0;
283 if (r == 0 || socket_errno == ENOTSOCK)
284 ioctl (fd, FIONREAD, &r);
287 r = recv (fd, data, sizeof (data), MSG_PEEK);
288 socket_errno = (r < 0) ? errno : 0;
293 /* If the event happened on an unconnected server socket,
295 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
296 happened |= (POLLIN | POLLRDNORM) & sought;
298 /* Distinguish hung-up sockets from other errors. */
299 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
300 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
307 if (FD_ISSET (fd, wfds))
308 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
310 if (FD_ISSET (fd, efds))
311 happened |= (POLLPRI | POLLRDBAND) & sought;
318 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
321 fd_set rfds, wfds, efds;
328 static int sc_open_max = -1;
331 || (nfd > sc_open_max
332 && (sc_open_max != -1
333 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
338 # else /* !_SC_OPEN_MAX */
340 if (nfd < 0 || nfd > OPEN_MAX)
345 # endif /* OPEN_MAX -- else, no check is needed */
346 # endif /* !_SC_OPEN_MAX */
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++)
388 if (pfd[i].events & (POLLIN | POLLRDNORM))
389 FD_SET (pfd[i].fd, &rfds);
391 /* see select(2): "the only exceptional condition detectable
392 is out-of-band data received on a socket", hence we push
393 POLLWRBAND events onto wfds instead of efds. */
394 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
395 FD_SET (pfd[i].fd, &wfds);
396 if (pfd[i].events & (POLLPRI | POLLRDBAND))
397 FD_SET (pfd[i].fd, &efds);
398 if (pfd[i].fd >= maxfd
399 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
400 | POLLRDNORM | POLLRDBAND
401 | POLLWRNORM | POLLWRBAND)))
404 if (maxfd > FD_SETSIZE)
412 /* examine fd sets */
413 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
417 /* establish results */
419 for (i = 0; i < nfd; i++)
424 int happened = compute_revents (pfd[i].fd, pfd[i].events,
425 &rfds, &wfds, &efds);
428 pfd[i].revents = happened;
435 static struct timeval tv0;
436 static HANDLE hEvent;
438 HANDLE h, handle_array[FD_SETSIZE + 2];
439 DWORD ret, wait_timeout, nhandles;
440 fd_set rfds, wfds, xfds;
446 if (nfd < 0 || timeout < -1)
453 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
455 handle_array[0] = hEvent;
461 /* Classify socket handles and create fd sets. */
462 for (i = 0; i < nfd; i++)
464 int sought = pfd[i].events;
468 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
469 | POLLPRI | POLLRDBAND)))
472 h = (HANDLE) _get_osfhandle (pfd[i].fd);
474 if (IsSocketHandle (h))
476 int requested = FD_CLOSE;
478 /* see above; socket handles are mapped onto select. */
479 if (sought & (POLLIN | POLLRDNORM))
481 requested |= FD_READ | FD_ACCEPT;
482 FD_SET ((SOCKET) h, &rfds);
484 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
486 requested |= FD_WRITE | FD_CONNECT;
487 FD_SET ((SOCKET) h, &wfds);
489 if (sought & (POLLPRI | POLLRDBAND))
492 FD_SET ((SOCKET) h, &xfds);
496 WSAEventSelect ((SOCKET) h, hEvent, requested);
500 /* Poll now. If we get an event, do not poll again. Also,
501 screen buffer handles are waitable, and they'll block until
502 a character is available. win32_compute_revents eliminates
503 bits for the "wrong" direction. */
504 pfd[i].revents = win32_compute_revents (h, &sought);
506 handle_array[nhandles++] = h;
512 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
514 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
515 no need to call select again. */
522 if (timeout == INFTIM)
523 wait_timeout = INFINITE;
525 wait_timeout = timeout;
530 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
531 wait_timeout, QS_ALLINPUT);
533 if (ret == WAIT_OBJECT_0 + nhandles)
535 /* new input of some other kind */
537 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
539 TranslateMessage (&msg);
540 DispatchMessage (&msg);
548 select (0, &rfds, &wfds, &xfds, &tv0);
550 /* Place a sentinel at the end of the array. */
551 handle_array[nhandles] = NULL;
553 for (i = 0; i < nfd; i++)
559 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
560 POLLOUT | POLLWRNORM | POLLWRBAND)))
563 h = (HANDLE) _get_osfhandle (pfd[i].fd);
564 if (h != handle_array[nhandles])
567 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
568 WSAEventSelect ((SOCKET) h, 0, 0);
570 /* If we're lucky, WSAEnumNetworkEvents already provided a way
571 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
572 if (FD_ISSET ((SOCKET) h, &rfds)
573 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
574 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
575 if (FD_ISSET ((SOCKET) h, &wfds))
576 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
577 if (FD_ISSET ((SOCKET) h, &xfds))
578 ev.lNetworkEvents |= FD_OOB;
580 happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
586 int sought = pfd[i].events;
587 happened = win32_compute_revents (h, &sought);
591 if ((pfd[i].revents |= happened) != 0)