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>
36 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38 # include <winsock2.h>
44 # include <sys/time.h>
45 # include <sys/socket.h>
46 # include <sys/select.h>
50 #ifdef HAVE_SYS_IOCTL_H
51 # include <sys/ioctl.h>
53 #ifdef HAVE_SYS_FILIO_H
54 # include <sys/filio.h>
63 /* BeOS does not have MSG_PEEK. */
70 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
73 IsSocketHandle (HANDLE h)
77 if (IsConsoleHandle (h))
80 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
81 WSAEnumNetworkEvents instead distinguishes the two correctly. */
82 ev.lNetworkEvents = 0xDEADBEEF;
83 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
84 return ev.lNetworkEvents != 0xDEADBEEF;
87 /* Declare data structures for ntdll functions. */
88 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
90 ULONG NamedPipeConfiguration;
91 ULONG MaximumInstances;
92 ULONG CurrentInstances;
94 ULONG ReadDataAvailable;
96 ULONG WriteQuotaAvailable;
99 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
101 typedef struct _IO_STATUS_BLOCK
107 ULONG_PTR Information;
108 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
110 typedef enum _FILE_INFORMATION_CLASS {
111 FilePipeLocalInformation = 24
112 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
114 typedef DWORD (WINAPI *PNtQueryInformationFile)
115 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
118 # define PIPE_BUF 512
121 /* Compute revents values for file handle H. If some events cannot happen
122 for the handle, eliminate them from *P_SOUGHT. */
125 win32_compute_revents (HANDLE h, int *p_sought)
127 int i, ret, happened;
128 INPUT_RECORD *irbuffer;
129 DWORD avail, nbuffer;
131 IO_STATUS_BLOCK iosb;
132 FILE_PIPE_LOCAL_INFORMATION fpli;
133 static PNtQueryInformationFile NtQueryInformationFile;
134 static BOOL once_only;
136 switch (GetFileType (h))
141 NtQueryInformationFile = (PNtQueryInformationFile)
142 GetProcAddress (GetModuleHandle ("ntdll.dll"),
143 "NtQueryInformationFile");
148 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
151 happened |= *p_sought & (POLLIN | POLLRDNORM);
156 /* It was the write-end of the pipe. Check if it is writable.
157 If NtQueryInformationFile fails, optimistically assume the pipe is
158 writable. This could happen on Win9x, where NtQueryInformationFile
159 is not available, or if we inherit a pipe that doesn't permit
160 FILE_READ_ATTRIBUTES access on the write end (I think this should
161 not happen since WinXP SP2; WINE seems fine too). Otherwise,
162 ensure that enough space is available for atomic writes. */
163 memset (&iosb, 0, sizeof (iosb));
164 memset (&fpli, 0, sizeof (fpli));
166 if (!NtQueryInformationFile
167 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
168 FilePipeLocalInformation)
169 || fpli.WriteQuotaAvailable >= PIPE_BUF
170 || (fpli.OutboundQuota < PIPE_BUF &&
171 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
172 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
177 ret = WaitForSingleObject (h, 0);
178 if (!IsConsoleHandle (h))
179 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
182 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
186 *p_sought &= POLLIN | POLLRDNORM;
192 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
193 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
194 if (!bRet || avail == 0)
197 for (i = 0; i < avail; i++)
198 if (irbuffer[i].EventType == KEY_EVENT)
205 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
210 ret = WaitForSingleObject (h, 0);
211 if (ret == WAIT_OBJECT_0)
212 return *p_sought & ~(POLLPRI | POLLRDBAND);
214 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
218 /* Convert fd_sets returned by select into revents values. */
221 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
225 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
226 happened |= (POLLIN | POLLRDNORM) & sought;
228 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
234 r = recv (h, data, sizeof (data), MSG_PEEK);
235 error = WSAGetLastError ();
238 if (r > 0 || error == WSAENOTCONN)
239 happened |= (POLLIN | POLLRDNORM) & sought;
241 /* Distinguish hung-up sockets from other errors. */
242 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
243 || error == WSAECONNABORTED || error == WSAENETRESET)
250 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
251 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
253 if (lNetworkEvents & FD_OOB)
254 happened |= (POLLPRI | POLLRDBAND) & sought;
261 /* Convert select(2) returned fd_sets into poll(2) revents values. */
263 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
266 if (FD_ISSET (fd, rfds))
271 # if defined __MACH__ && defined __APPLE__
272 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
273 for some kinds of descriptors. Detect if this descriptor is a
274 connected socket, a server socket, or something else using a
275 0-byte recv, and use ioctl(2) to detect POLLHUP. */
276 r = recv (fd, NULL, 0, MSG_PEEK);
277 socket_errno = (r < 0) ? errno : 0;
278 if (r == 0 || socket_errno == ENOTSOCK)
279 ioctl (fd, FIONREAD, &r);
282 r = recv (fd, data, sizeof (data), MSG_PEEK);
283 socket_errno = (r < 0) ? errno : 0;
288 /* If the event happened on an unconnected server socket,
290 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
291 happened |= (POLLIN | POLLRDNORM) & sought;
293 /* Distinguish hung-up sockets from other errors. */
294 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
295 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
302 if (FD_ISSET (fd, wfds))
303 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
305 if (FD_ISSET (fd, efds))
306 happened |= (POLLPRI | POLLRDBAND) & sought;
313 poll (pfd, nfd, timeout)
319 fd_set rfds, wfds, efds;
326 static int sc_open_max = -1;
329 || (nfd > sc_open_max
330 && (sc_open_max != -1
331 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
336 # else /* !_SC_OPEN_MAX */
338 if (nfd < 0 || nfd > OPEN_MAX)
343 # endif /* OPEN_MAX -- else, no check is needed */
344 # endif /* !_SC_OPEN_MAX */
346 /* EFAULT is not necessary to implement, but let's do it in the
354 /* convert timeout number into a timeval structure */
361 else if (timeout > 0)
364 ptv->tv_sec = timeout / 1000;
365 ptv->tv_usec = (timeout % 1000) * 1000;
367 else if (timeout == INFTIM)
376 /* create fd sets and determine max fd */
381 for (i = 0; i < nfd; i++)
386 if (pfd[i].events & (POLLIN | POLLRDNORM))
387 FD_SET (pfd[i].fd, &rfds);
389 /* see select(2): "the only exceptional condition detectable
390 is out-of-band data received on a socket", hence we push
391 POLLWRBAND events onto wfds instead of efds. */
392 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
393 FD_SET (pfd[i].fd, &wfds);
394 if (pfd[i].events & (POLLPRI | POLLRDBAND))
395 FD_SET (pfd[i].fd, &efds);
396 if (pfd[i].fd >= maxfd
397 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
398 | POLLRDNORM | POLLRDBAND
399 | POLLWRNORM | POLLWRBAND)))
402 if (maxfd > FD_SETSIZE)
410 /* examine fd sets */
411 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
415 /* establish results */
417 for (i = 0; i < nfd; i++)
422 int happened = compute_revents (pfd[i].fd, pfd[i].events,
423 &rfds, &wfds, &efds);
426 pfd[i].revents = happened;
433 static struct timeval tv0;
434 static HANDLE hEvent;
436 HANDLE h, handle_array[FD_SETSIZE + 2];
437 DWORD ret, wait_timeout, nhandles;
438 fd_set rfds, wfds, xfds;
444 if (nfd < 0 || timeout < -1)
451 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
453 handle_array[0] = hEvent;
459 /* Classify socket handles and create fd sets. */
460 for (i = 0; i < nfd; i++)
462 int sought = pfd[i].events;
466 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
467 | POLLPRI | POLLRDBAND)))
470 h = (HANDLE) _get_osfhandle (pfd[i].fd);
472 if (IsSocketHandle (h))
474 int requested = FD_CLOSE;
476 /* see above; socket handles are mapped onto select. */
477 if (sought & (POLLIN | POLLRDNORM))
479 requested |= FD_READ | FD_ACCEPT;
480 FD_SET ((SOCKET) h, &rfds);
482 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
484 requested |= FD_WRITE | FD_CONNECT;
485 FD_SET ((SOCKET) h, &wfds);
487 if (sought & (POLLPRI | POLLRDBAND))
490 FD_SET ((SOCKET) h, &xfds);
494 WSAEventSelect ((SOCKET) h, hEvent, requested);
498 /* Poll now. If we get an event, do not poll again. Also,
499 screen buffer handles are waitable, and they'll block until
500 a character is available. win32_compute_revents eliminates
501 bits for the "wrong" direction. */
502 pfd[i].revents = win32_compute_revents (h, &sought);
504 handle_array[nhandles++] = h;
510 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
512 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
513 no need to call select again. */
520 if (timeout == INFTIM)
521 wait_timeout = INFINITE;
523 wait_timeout = timeout;
528 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
529 wait_timeout, QS_ALLINPUT);
531 if (ret == WAIT_OBJECT_0 + nhandles)
533 /* new input of some other kind */
535 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
537 TranslateMessage (&msg);
538 DispatchMessage (&msg);
546 select (0, &rfds, &wfds, &xfds, &tv0);
548 /* Place a sentinel at the end of the array. */
549 handle_array[nhandles] = NULL;
551 for (i = 0; i < nfd; i++)
557 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
558 POLLOUT | POLLWRNORM | POLLWRBAND)))
561 h = (HANDLE) _get_osfhandle (pfd[i].fd);
562 if (h != handle_array[nhandles])
565 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
566 WSAEventSelect ((SOCKET) h, 0, 0);
568 /* If we're lucky, WSAEnumNetworkEvents already provided a way
569 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
570 if (FD_ISSET ((SOCKET) h, &rfds)
571 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
572 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
573 if (FD_ISSET ((SOCKET) h, &wfds))
574 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
575 if (FD_ISSET ((SOCKET) h, &xfds))
576 ev.lNetworkEvents |= FD_OOB;
578 happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
584 int sought = pfd[i].events;
585 happened = win32_compute_revents (h, &sought);
589 if ((pfd[i].revents |= happened) != 0)