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"
31 #include <sys/types.h>
40 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
42 # if defined (_MSC_VER)
43 # define _WIN32_WINNT 0x0502
45 # include <winsock2.h>
51 # include <sys/time.h>
52 # include <sys/socket.h>
53 # ifndef NO_SYS_SELECT_H
54 # include <sys/select.h>
59 #ifdef HAVE_SYS_IOCTL_H
60 # include <sys/ioctl.h>
62 #ifdef HAVE_SYS_FILIO_H
63 # include <sys/filio.h>
72 /* BeOS does not have MSG_PEEK. */
79 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
82 IsSocketHandle (HANDLE h
)
86 if (IsConsoleHandle (h
))
89 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
90 WSAEnumNetworkEvents instead distinguishes the two correctly. */
91 ev
.lNetworkEvents
= 0xDEADBEEF;
92 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
93 return ev
.lNetworkEvents
!= 0xDEADBEEF;
96 /* Declare data structures for ntdll functions. */
97 typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
99 ULONG NamedPipeConfiguration
;
100 ULONG MaximumInstances
;
101 ULONG CurrentInstances
;
103 ULONG ReadDataAvailable
;
105 ULONG WriteQuotaAvailable
;
106 ULONG NamedPipeState
;
108 } FILE_PIPE_LOCAL_INFORMATION
, *PFILE_PIPE_LOCAL_INFORMATION
;
110 typedef struct _IO_STATUS_BLOCK
116 ULONG_PTR Information
;
117 } IO_STATUS_BLOCK
, *PIO_STATUS_BLOCK
;
119 typedef enum _FILE_INFORMATION_CLASS
{
120 FilePipeLocalInformation
= 24
121 } FILE_INFORMATION_CLASS
, *PFILE_INFORMATION_CLASS
;
123 typedef DWORD (WINAPI
*PNtQueryInformationFile
)
124 (HANDLE
, IO_STATUS_BLOCK
*, VOID
*, ULONG
, FILE_INFORMATION_CLASS
);
127 # define PIPE_BUF 512
130 /* Compute revents values for file handle H. If some events cannot happen
131 for the handle, eliminate them from *P_SOUGHT. */
134 win32_compute_revents (HANDLE h
, int *p_sought
)
136 int i
, ret
, happened
;
137 INPUT_RECORD
*irbuffer
;
138 DWORD avail
, nbuffer
;
140 IO_STATUS_BLOCK iosb
;
141 FILE_PIPE_LOCAL_INFORMATION fpli
;
142 static PNtQueryInformationFile NtQueryInformationFile
;
143 static BOOL once_only
;
145 switch (GetFileType (h
))
150 NtQueryInformationFile
= (PNtQueryInformationFile
)
151 GetProcAddress (GetModuleHandle ("ntdll.dll"),
152 "NtQueryInformationFile");
157 if (PeekNamedPipe (h
, NULL
, 0, NULL
, &avail
, NULL
) != 0)
160 happened
|= *p_sought
& (POLLIN
| POLLRDNORM
);
162 else if (GetLastError () == ERROR_BROKEN_PIPE
)
167 /* It was the write-end of the pipe. Check if it is writable.
168 If NtQueryInformationFile fails, optimistically assume the pipe is
169 writable. This could happen on Win9x, where NtQueryInformationFile
170 is not available, or if we inherit a pipe that doesn't permit
171 FILE_READ_ATTRIBUTES access on the write end (I think this should
172 not happen since WinXP SP2; WINE seems fine too). Otherwise,
173 ensure that enough space is available for atomic writes. */
174 memset (&iosb
, 0, sizeof (iosb
));
175 memset (&fpli
, 0, sizeof (fpli
));
177 if (!NtQueryInformationFile
178 || NtQueryInformationFile (h
, &iosb
, &fpli
, sizeof (fpli
),
179 FilePipeLocalInformation
)
180 || fpli
.WriteQuotaAvailable
>= PIPE_BUF
181 || (fpli
.OutboundQuota
< PIPE_BUF
&&
182 fpli
.WriteQuotaAvailable
== fpli
.OutboundQuota
))
183 happened
|= *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
188 ret
= WaitForSingleObject (h
, 0);
189 if (!IsConsoleHandle (h
))
190 return ret
== WAIT_OBJECT_0
? *p_sought
& ~(POLLPRI
| POLLRDBAND
) : 0;
193 bRet
= GetNumberOfConsoleInputEvents (h
, &nbuffer
);
197 *p_sought
&= POLLIN
| POLLRDNORM
;
203 irbuffer
= (INPUT_RECORD
*) alloca (nbuffer
* sizeof (INPUT_RECORD
));
204 bRet
= PeekConsoleInput (h
, irbuffer
, nbuffer
, &avail
);
205 if (!bRet
|| avail
== 0)
208 for (i
= 0; i
< avail
; i
++)
209 if (irbuffer
[i
].EventType
== KEY_EVENT
)
216 *p_sought
&= POLLOUT
| POLLWRNORM
| POLLWRBAND
;
221 ret
= WaitForSingleObject (h
, 0);
222 if (ret
== WAIT_OBJECT_0
)
223 return *p_sought
& ~(POLLPRI
| POLLRDBAND
);
225 return *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
229 /* Convert fd_sets returned by select into revents values. */
232 win32_compute_revents_socket (SOCKET h
, int sought
, long lNetworkEvents
)
236 if ((lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
)) == FD_ACCEPT
)
237 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
239 else if (lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
))
245 r
= recv (h
, data
, sizeof (data
), MSG_PEEK
);
246 error
= WSAGetLastError ();
249 if (r
> 0 || error
== WSAENOTCONN
)
250 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
252 /* Distinguish hung-up sockets from other errors. */
253 else if (r
== 0 || error
== WSAESHUTDOWN
|| error
== WSAECONNRESET
254 || error
== WSAECONNABORTED
|| error
== WSAENETRESET
)
261 if (lNetworkEvents
& (FD_WRITE
| FD_CONNECT
))
262 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
264 if (lNetworkEvents
& FD_OOB
)
265 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
272 /* Convert select(2) returned fd_sets into poll(2) revents values. */
274 compute_revents (int fd
, int sought
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*efds
)
277 if (FD_ISSET (fd
, rfds
))
282 # if defined __MACH__ && defined __APPLE__
283 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
284 for some kinds of descriptors. Detect if this descriptor is a
285 connected socket, a server socket, or something else using a
286 0-byte recv, and use ioctl(2) to detect POLLHUP. */
287 r
= recv (fd
, NULL
, 0, MSG_PEEK
);
288 socket_errno
= (r
< 0) ? errno
: 0;
289 if (r
== 0 || socket_errno
== ENOTSOCK
)
290 ioctl (fd
, FIONREAD
, &r
);
293 r
= recv (fd
, data
, sizeof (data
), MSG_PEEK
);
294 socket_errno
= (r
< 0) ? errno
: 0;
299 /* If the event happened on an unconnected server socket,
301 else if (r
> 0 || ( /* (r == -1) && */ socket_errno
== ENOTCONN
))
302 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
304 /* Distinguish hung-up sockets from other errors. */
305 else if (socket_errno
== ESHUTDOWN
|| socket_errno
== ECONNRESET
306 || socket_errno
== ECONNABORTED
|| socket_errno
== ENETRESET
)
309 /* some systems can't use recv() on non-socket, including HP NonStop */
310 else if (/* (r == -1) && */ socket_errno
== ENOTSOCK
)
311 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
317 if (FD_ISSET (fd
, wfds
))
318 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
320 if (FD_ISSET (fd
, efds
))
321 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
328 poll (struct pollfd
*pfd
, nfds_t nfd
, int timeout
)
331 fd_set rfds
, wfds
, efds
;
338 static int sc_open_max
= -1;
341 || (nfd
> sc_open_max
342 && (sc_open_max
!= -1
343 || nfd
> (sc_open_max
= sysconf (_SC_OPEN_MAX
)))))
348 # else /* !_SC_OPEN_MAX */
350 if (nfd
< 0 || nfd
> OPEN_MAX
)
355 # endif /* OPEN_MAX -- else, no check is needed */
356 # endif /* !_SC_OPEN_MAX */
358 /* EFAULT is not necessary to implement, but let's do it in the
366 /* convert timeout number into a timeval structure */
373 else if (timeout
> 0)
376 ptv
->tv_sec
= timeout
/ 1000;
377 ptv
->tv_usec
= (timeout
% 1000) * 1000;
379 else if (timeout
== INFTIM
)
388 /* create fd sets and determine max fd */
393 for (i
= 0; i
< nfd
; i
++)
398 if (pfd
[i
].events
& (POLLIN
| POLLRDNORM
))
399 FD_SET (pfd
[i
].fd
, &rfds
);
401 /* see select(2): "the only exceptional condition detectable
402 is out-of-band data received on a socket", hence we push
403 POLLWRBAND events onto wfds instead of efds. */
404 if (pfd
[i
].events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
405 FD_SET (pfd
[i
].fd
, &wfds
);
406 if (pfd
[i
].events
& (POLLPRI
| POLLRDBAND
))
407 FD_SET (pfd
[i
].fd
, &efds
);
408 if (pfd
[i
].fd
>= maxfd
409 && (pfd
[i
].events
& (POLLIN
| POLLOUT
| POLLPRI
410 | POLLRDNORM
| POLLRDBAND
411 | POLLWRNORM
| POLLWRBAND
)))
414 if (maxfd
> FD_SETSIZE
)
422 /* examine fd sets */
423 rc
= select (maxfd
+ 1, &rfds
, &wfds
, &efds
, ptv
);
427 /* establish results */
429 for (i
= 0; i
< nfd
; i
++)
434 int happened
= compute_revents (pfd
[i
].fd
, pfd
[i
].events
,
435 &rfds
, &wfds
, &efds
);
438 pfd
[i
].revents
= happened
;
445 static struct timeval tv0
;
446 static HANDLE hEvent
;
448 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
449 DWORD ret
, wait_timeout
, nhandles
;
450 fd_set rfds
, wfds
, xfds
;
456 if (nfd
< 0 || timeout
< -1)
463 hEvent
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
466 handle_array
[0] = hEvent
;
472 /* Classify socket handles and create fd sets. */
473 for (i
= 0; i
< nfd
; i
++)
475 int sought
= pfd
[i
].events
;
479 if (!(sought
& (POLLIN
| POLLRDNORM
| POLLOUT
| POLLWRNORM
| POLLWRBAND
480 | POLLPRI
| POLLRDBAND
)))
483 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
485 if (IsSocketHandle (h
))
487 int requested
= FD_CLOSE
;
489 /* see above; socket handles are mapped onto select. */
490 if (sought
& (POLLIN
| POLLRDNORM
))
492 requested
|= FD_READ
| FD_ACCEPT
;
493 FD_SET ((SOCKET
) h
, &rfds
);
495 if (sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
497 requested
|= FD_WRITE
| FD_CONNECT
;
498 FD_SET ((SOCKET
) h
, &wfds
);
500 if (sought
& (POLLPRI
| POLLRDBAND
))
503 FD_SET ((SOCKET
) h
, &xfds
);
507 WSAEventSelect ((SOCKET
) h
, hEvent
, requested
);
511 /* Poll now. If we get an event, do not poll again. Also,
512 screen buffer handles are waitable, and they'll block until
513 a character is available. win32_compute_revents eliminates
514 bits for the "wrong" direction. */
515 pfd
[i
].revents
= win32_compute_revents (h
, &sought
);
517 handle_array
[nhandles
++] = h
;
523 if (select (0, &rfds
, &wfds
, &xfds
, &tv0
) > 0)
525 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
526 no need to call select again. */
533 if (timeout
== INFTIM
)
534 wait_timeout
= INFINITE
;
536 wait_timeout
= timeout
;
541 ret
= MsgWaitForMultipleObjects (nhandles
, handle_array
, FALSE
,
542 wait_timeout
, QS_ALLINPUT
);
544 if (ret
== WAIT_OBJECT_0
+ nhandles
)
546 /* new input of some other kind */
548 while ((bRet
= PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
)) != 0)
550 TranslateMessage (&msg
);
551 DispatchMessage (&msg
);
559 select (0, &rfds
, &wfds
, &xfds
, &tv0
);
561 /* Place a sentinel at the end of the array. */
562 handle_array
[nhandles
] = NULL
;
564 for (i
= 0; i
< nfd
; i
++)
570 if (!(pfd
[i
].events
& (POLLIN
| POLLRDNORM
|
571 POLLOUT
| POLLWRNORM
| POLLWRBAND
)))
574 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
575 if (h
!= handle_array
[nhandles
])
578 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
579 WSAEventSelect ((SOCKET
) h
, 0, 0);
581 /* If we're lucky, WSAEnumNetworkEvents already provided a way
582 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
583 if (FD_ISSET ((SOCKET
) h
, &rfds
)
584 && !(ev
.lNetworkEvents
& (FD_READ
| FD_ACCEPT
)))
585 ev
.lNetworkEvents
|= FD_READ
| FD_ACCEPT
;
586 if (FD_ISSET ((SOCKET
) h
, &wfds
))
587 ev
.lNetworkEvents
|= FD_WRITE
| FD_CONNECT
;
588 if (FD_ISSET ((SOCKET
) h
, &xfds
))
589 ev
.lNetworkEvents
|= FD_OOB
;
591 happened
= win32_compute_revents_socket ((SOCKET
) h
, pfd
[i
].events
,
597 int sought
= pfd
[i
].events
;
598 happened
= win32_compute_revents (h
, &sought
);
602 if ((pfd
[i
].revents
|= happened
) != 0)
606 if (!rc
&& timeout
== INFTIM
)