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"
29 #include <sys/types.h>
35 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
37 # include <winsock2.h>
43 # include <sys/time.h>
44 # include <sys/socket.h>
45 # include <sys/select.h>
49 #ifdef HAVE_SYS_IOCTL_H
50 # include <sys/ioctl.h>
52 #ifdef HAVE_SYS_FILIO_H
53 # include <sys/filio.h>
62 /* BeOS does not have MSG_PEEK. */
69 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
72 IsSocketHandle (HANDLE h
)
76 if (IsConsoleHandle (h
))
79 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
80 WSAEnumNetworkEvents instead distinguishes the two correctly. */
81 ev
.lNetworkEvents
= 0xDEADBEEF;
82 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
83 return ev
.lNetworkEvents
!= 0xDEADBEEF;
86 /* Declare data structures for ntdll functions. */
87 typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
89 ULONG NamedPipeConfiguration
;
90 ULONG MaximumInstances
;
91 ULONG CurrentInstances
;
93 ULONG ReadDataAvailable
;
95 ULONG WriteQuotaAvailable
;
98 } FILE_PIPE_LOCAL_INFORMATION
, *PFILE_PIPE_LOCAL_INFORMATION
;
100 typedef struct _IO_STATUS_BLOCK
106 ULONG_PTR Information
;
107 } IO_STATUS_BLOCK
, *PIO_STATUS_BLOCK
;
109 typedef enum _FILE_INFORMATION_CLASS
{
110 FilePipeLocalInformation
= 24
111 } FILE_INFORMATION_CLASS
, *PFILE_INFORMATION_CLASS
;
113 typedef DWORD (WINAPI
*PNtQueryInformationFile
)
114 (HANDLE
, IO_STATUS_BLOCK
*, VOID
*, ULONG
, FILE_INFORMATION_CLASS
);
117 # define PIPE_BUF 512
120 /* Compute revents values for file handle H. If some events cannot happen
121 for the handle, eliminate them from *P_SOUGHT. */
124 win32_compute_revents (HANDLE h
, int *p_sought
)
126 int i
, ret
, happened
;
127 INPUT_RECORD
*irbuffer
;
128 DWORD avail
, nbuffer
;
130 IO_STATUS_BLOCK iosb
;
131 FILE_PIPE_LOCAL_INFORMATION fpli
;
132 static PNtQueryInformationFile NtQueryInformationFile
;
133 static BOOL once_only
;
135 switch (GetFileType (h
))
140 NtQueryInformationFile
= (PNtQueryInformationFile
)
141 GetProcAddress (GetModuleHandle ("ntdll.dll"),
142 "NtQueryInformationFile");
147 if (PeekNamedPipe (h
, NULL
, 0, NULL
, &avail
, NULL
) != 0)
150 happened
|= *p_sought
& (POLLIN
| POLLRDNORM
);
152 else if (GetLastError () == ERROR_BROKEN_PIPE
)
157 /* It was the write-end of the pipe. Check if it is writable.
158 If NtQueryInformationFile fails, optimistically assume the pipe is
159 writable. This could happen on Win9x, where NtQueryInformationFile
160 is not available, or if we inherit a pipe that doesn't permit
161 FILE_READ_ATTRIBUTES access on the write end (I think this should
162 not happen since WinXP SP2; WINE seems fine too). Otherwise,
163 ensure that enough space is available for atomic writes. */
164 memset (&iosb
, 0, sizeof (iosb
));
165 memset (&fpli
, 0, sizeof (fpli
));
167 if (!NtQueryInformationFile
168 || NtQueryInformationFile (h
, &iosb
, &fpli
, sizeof (fpli
),
169 FilePipeLocalInformation
)
170 || fpli
.WriteQuotaAvailable
>= PIPE_BUF
171 || (fpli
.OutboundQuota
< PIPE_BUF
&&
172 fpli
.WriteQuotaAvailable
== fpli
.OutboundQuota
))
173 happened
|= *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
178 ret
= WaitForSingleObject (h
, 0);
179 if (!IsConsoleHandle (h
))
180 return ret
== WAIT_OBJECT_0
? *p_sought
& ~(POLLPRI
| POLLRDBAND
) : 0;
183 bRet
= GetNumberOfConsoleInputEvents (h
, &nbuffer
);
187 *p_sought
&= POLLIN
| POLLRDNORM
;
193 irbuffer
= (INPUT_RECORD
*) alloca (nbuffer
* sizeof (INPUT_RECORD
));
194 bRet
= PeekConsoleInput (h
, irbuffer
, nbuffer
, &avail
);
195 if (!bRet
|| avail
== 0)
198 for (i
= 0; i
< avail
; i
++)
199 if (irbuffer
[i
].EventType
== KEY_EVENT
)
206 *p_sought
&= POLLOUT
| POLLWRNORM
| POLLWRBAND
;
211 ret
= WaitForSingleObject (h
, 0);
212 if (ret
== WAIT_OBJECT_0
)
213 return *p_sought
& ~(POLLPRI
| POLLRDBAND
);
215 return *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
219 /* Convert fd_sets returned by select into revents values. */
222 win32_compute_revents_socket (SOCKET h
, int sought
, long lNetworkEvents
)
226 if ((lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
)) == FD_ACCEPT
)
227 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
229 else if (lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
))
235 r
= recv (h
, data
, sizeof (data
), MSG_PEEK
);
236 error
= WSAGetLastError ();
239 if (r
> 0 || error
== WSAENOTCONN
)
240 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
242 /* Distinguish hung-up sockets from other errors. */
243 else if (r
== 0 || error
== WSAESHUTDOWN
|| error
== WSAECONNRESET
244 || error
== WSAECONNABORTED
|| error
== WSAENETRESET
)
251 if (lNetworkEvents
& (FD_WRITE
| FD_CONNECT
))
252 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
254 if (lNetworkEvents
& FD_OOB
)
255 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
262 /* Convert select(2) returned fd_sets into poll(2) revents values. */
264 compute_revents (int fd
, int sought
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*efds
)
267 if (FD_ISSET (fd
, rfds
))
272 # if defined __MACH__ && defined __APPLE__
273 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
274 for some kinds of descriptors. Detect if this descriptor is a
275 connected socket, a server socket, or something else using a
276 0-byte recv, and use ioctl(2) to detect POLLHUP. */
277 r
= recv (fd
, NULL
, 0, MSG_PEEK
);
278 socket_errno
= (r
< 0) ? errno
: 0;
279 if (r
== 0 || socket_errno
== ENOTSOCK
)
280 ioctl (fd
, FIONREAD
, &r
);
283 r
= recv (fd
, data
, sizeof (data
), MSG_PEEK
);
284 socket_errno
= (r
< 0) ? errno
: 0;
289 /* If the event happened on an unconnected server socket,
291 else if (r
> 0 || ( /* (r == -1) && */ socket_errno
== ENOTCONN
))
292 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
294 /* Distinguish hung-up sockets from other errors. */
295 else if (socket_errno
== ESHUTDOWN
|| socket_errno
== ECONNRESET
296 || socket_errno
== ECONNABORTED
|| socket_errno
== ENETRESET
)
303 if (FD_ISSET (fd
, wfds
))
304 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
306 if (FD_ISSET (fd
, efds
))
307 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
314 poll (pfd
, nfd
, timeout
)
320 fd_set rfds
, wfds
, efds
;
327 static int sc_open_max
= -1;
330 || (nfd
> sc_open_max
331 && (sc_open_max
!= -1
332 || nfd
> (sc_open_max
= sysconf (_SC_OPEN_MAX
)))))
337 # else /* !_SC_OPEN_MAX */
339 if (nfd
< 0 || nfd
> OPEN_MAX
)
344 # endif /* OPEN_MAX -- else, no check is needed */
345 # endif /* !_SC_OPEN_MAX */
347 /* EFAULT is not necessary to implement, but let's do it in the
355 /* convert timeout number into a timeval structure */
362 else if (timeout
> 0)
365 ptv
->tv_sec
= timeout
/ 1000;
366 ptv
->tv_usec
= (timeout
% 1000) * 1000;
368 else if (timeout
== INFTIM
)
377 /* create fd sets and determine max fd */
382 for (i
= 0; i
< nfd
; i
++)
387 if (pfd
[i
].events
& (POLLIN
| POLLRDNORM
))
388 FD_SET (pfd
[i
].fd
, &rfds
);
390 /* see select(2): "the only exceptional condition detectable
391 is out-of-band data received on a socket", hence we push
392 POLLWRBAND events onto wfds instead of efds. */
393 if (pfd
[i
].events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
394 FD_SET (pfd
[i
].fd
, &wfds
);
395 if (pfd
[i
].events
& (POLLPRI
| POLLRDBAND
))
396 FD_SET (pfd
[i
].fd
, &efds
);
397 if (pfd
[i
].fd
>= maxfd
398 && (pfd
[i
].events
& (POLLIN
| POLLOUT
| POLLPRI
399 | POLLRDNORM
| POLLRDBAND
400 | POLLWRNORM
| POLLWRBAND
)))
403 if (maxfd
> FD_SETSIZE
)
411 /* examine fd sets */
412 rc
= select (maxfd
+ 1, &rfds
, &wfds
, &efds
, ptv
);
416 /* establish results */
418 for (i
= 0; i
< nfd
; i
++)
423 int happened
= compute_revents (pfd
[i
].fd
, pfd
[i
].events
,
424 &rfds
, &wfds
, &efds
);
427 pfd
[i
].revents
= happened
;
434 static struct timeval tv0
;
435 static HANDLE hEvent
;
437 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
438 DWORD ret
, wait_timeout
, nhandles
;
439 fd_set rfds
, wfds
, xfds
;
445 if (nfd
< 0 || timeout
< -1)
452 hEvent
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
454 handle_array
[0] = hEvent
;
460 /* Classify socket handles and create fd sets. */
461 for (i
= 0; i
< nfd
; i
++)
463 int sought
= pfd
[i
].events
;
467 if (!(sought
& (POLLIN
| POLLRDNORM
| POLLOUT
| POLLWRNORM
| POLLWRBAND
468 | POLLPRI
| POLLRDBAND
)))
471 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
473 if (IsSocketHandle (h
))
475 int requested
= FD_CLOSE
;
477 /* see above; socket handles are mapped onto select. */
478 if (sought
& (POLLIN
| POLLRDNORM
))
480 requested
|= FD_READ
| FD_ACCEPT
;
481 FD_SET ((SOCKET
) h
, &rfds
);
483 if (sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
485 requested
|= FD_WRITE
| FD_CONNECT
;
486 FD_SET ((SOCKET
) h
, &wfds
);
488 if (sought
& (POLLPRI
| POLLRDBAND
))
491 FD_SET ((SOCKET
) h
, &xfds
);
495 WSAEventSelect ((SOCKET
) h
, hEvent
, requested
);
499 /* Poll now. If we get an event, do not poll again. Also,
500 screen buffer handles are waitable, and they'll block until
501 a character is available. win32_compute_revents eliminates
502 bits for the "wrong" direction. */
503 pfd
[i
].revents
= win32_compute_revents (h
, &sought
);
505 handle_array
[nhandles
++] = h
;
511 if (select (0, &rfds
, &wfds
, &xfds
, &tv0
) > 0)
513 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
514 no need to call select again. */
521 if (timeout
== INFTIM
)
522 wait_timeout
= INFINITE
;
524 wait_timeout
= timeout
;
529 ret
= MsgWaitForMultipleObjects (nhandles
, handle_array
, FALSE
,
530 wait_timeout
, QS_ALLINPUT
);
532 if (ret
== WAIT_OBJECT_0
+ nhandles
)
534 /* new input of some other kind */
536 while ((bRet
= PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
)) != 0)
538 TranslateMessage (&msg
);
539 DispatchMessage (&msg
);
547 select (0, &rfds
, &wfds
, &xfds
, &tv0
);
549 /* Place a sentinel at the end of the array. */
550 handle_array
[nhandles
] = NULL
;
552 for (i
= 0; i
< nfd
; i
++)
558 if (!(pfd
[i
].events
& (POLLIN
| POLLRDNORM
|
559 POLLOUT
| POLLWRNORM
| POLLWRBAND
)))
562 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
563 if (h
!= handle_array
[nhandles
])
566 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
567 WSAEventSelect ((SOCKET
) h
, 0, 0);
569 /* If we're lucky, WSAEnumNetworkEvents already provided a way
570 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
571 if (FD_ISSET ((SOCKET
) h
, &rfds
)
572 && !(ev
.lNetworkEvents
& (FD_READ
| FD_ACCEPT
)))
573 ev
.lNetworkEvents
|= FD_READ
| FD_ACCEPT
;
574 if (FD_ISSET ((SOCKET
) h
, &wfds
))
575 ev
.lNetworkEvents
|= FD_WRITE
| FD_CONNECT
;
576 if (FD_ISSET ((SOCKET
) h
, &xfds
))
577 ev
.lNetworkEvents
|= FD_OOB
;
579 happened
= win32_compute_revents_socket ((SOCKET
) h
, pfd
[i
].events
,
585 int sought
= pfd
[i
].events
;
586 happened
= win32_compute_revents (h
, &sought
);
590 if ((pfd
[i
].revents
|= happened
) != 0)