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"
29 #include <sys/types.h>
38 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
40 # if defined (_MSC_VER)
41 # define _WIN32_WINNT 0x0502
43 # include <winsock2.h>
49 # include <sys/time.h>
50 # include <sys/socket.h>
51 # include <sys/select.h>
55 #ifdef HAVE_SYS_IOCTL_H
56 # include <sys/ioctl.h>
58 #ifdef HAVE_SYS_FILIO_H
59 # include <sys/filio.h>
68 /* BeOS does not have MSG_PEEK. */
75 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
78 IsSocketHandle (HANDLE h
)
82 if (IsConsoleHandle (h
))
85 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
86 WSAEnumNetworkEvents instead distinguishes the two correctly. */
87 ev
.lNetworkEvents
= 0xDEADBEEF;
88 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
89 return ev
.lNetworkEvents
!= 0xDEADBEEF;
92 /* Declare data structures for ntdll functions. */
93 typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
95 ULONG NamedPipeConfiguration
;
96 ULONG MaximumInstances
;
97 ULONG CurrentInstances
;
99 ULONG ReadDataAvailable
;
101 ULONG WriteQuotaAvailable
;
102 ULONG NamedPipeState
;
104 } FILE_PIPE_LOCAL_INFORMATION
, *PFILE_PIPE_LOCAL_INFORMATION
;
106 typedef struct _IO_STATUS_BLOCK
112 ULONG_PTR Information
;
113 } IO_STATUS_BLOCK
, *PIO_STATUS_BLOCK
;
115 typedef enum _FILE_INFORMATION_CLASS
{
116 FilePipeLocalInformation
= 24
117 } FILE_INFORMATION_CLASS
, *PFILE_INFORMATION_CLASS
;
119 typedef DWORD (WINAPI
*PNtQueryInformationFile
)
120 (HANDLE
, IO_STATUS_BLOCK
*, VOID
*, ULONG
, FILE_INFORMATION_CLASS
);
123 # define PIPE_BUF 512
126 /* Compute revents values for file handle H. If some events cannot happen
127 for the handle, eliminate them from *P_SOUGHT. */
130 win32_compute_revents (HANDLE h
, int *p_sought
)
132 int i
, ret
, happened
;
133 INPUT_RECORD
*irbuffer
;
134 DWORD avail
, nbuffer
;
136 IO_STATUS_BLOCK iosb
;
137 FILE_PIPE_LOCAL_INFORMATION fpli
;
138 static PNtQueryInformationFile NtQueryInformationFile
;
139 static BOOL once_only
;
141 switch (GetFileType (h
))
146 NtQueryInformationFile
= (PNtQueryInformationFile
)
147 GetProcAddress (GetModuleHandle ("ntdll.dll"),
148 "NtQueryInformationFile");
153 if (PeekNamedPipe (h
, NULL
, 0, NULL
, &avail
, NULL
) != 0)
156 happened
|= *p_sought
& (POLLIN
| POLLRDNORM
);
158 else if (GetLastError () == ERROR_BROKEN_PIPE
)
163 /* It was the write-end of the pipe. Check if it is writable.
164 If NtQueryInformationFile fails, optimistically assume the pipe is
165 writable. This could happen on Win9x, where NtQueryInformationFile
166 is not available, or if we inherit a pipe that doesn't permit
167 FILE_READ_ATTRIBUTES access on the write end (I think this should
168 not happen since WinXP SP2; WINE seems fine too). Otherwise,
169 ensure that enough space is available for atomic writes. */
170 memset (&iosb
, 0, sizeof (iosb
));
171 memset (&fpli
, 0, sizeof (fpli
));
173 if (!NtQueryInformationFile
174 || NtQueryInformationFile (h
, &iosb
, &fpli
, sizeof (fpli
),
175 FilePipeLocalInformation
)
176 || fpli
.WriteQuotaAvailable
>= PIPE_BUF
177 || (fpli
.OutboundQuota
< PIPE_BUF
&&
178 fpli
.WriteQuotaAvailable
== fpli
.OutboundQuota
))
179 happened
|= *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
184 ret
= WaitForSingleObject (h
, 0);
185 if (!IsConsoleHandle (h
))
186 return ret
== WAIT_OBJECT_0
? *p_sought
& ~(POLLPRI
| POLLRDBAND
) : 0;
189 bRet
= GetNumberOfConsoleInputEvents (h
, &nbuffer
);
193 *p_sought
&= POLLIN
| POLLRDNORM
;
199 irbuffer
= (INPUT_RECORD
*) alloca (nbuffer
* sizeof (INPUT_RECORD
));
200 bRet
= PeekConsoleInput (h
, irbuffer
, nbuffer
, &avail
);
201 if (!bRet
|| avail
== 0)
204 for (i
= 0; i
< avail
; i
++)
205 if (irbuffer
[i
].EventType
== KEY_EVENT
)
212 *p_sought
&= POLLOUT
| POLLWRNORM
| POLLWRBAND
;
217 ret
= WaitForSingleObject (h
, 0);
218 if (ret
== WAIT_OBJECT_0
)
219 return *p_sought
& ~(POLLPRI
| POLLRDBAND
);
221 return *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
225 /* Convert fd_sets returned by select into revents values. */
228 win32_compute_revents_socket (SOCKET h
, int sought
, long lNetworkEvents
)
232 if ((lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
)) == FD_ACCEPT
)
233 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
235 else if (lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
))
241 r
= recv (h
, data
, sizeof (data
), MSG_PEEK
);
242 error
= WSAGetLastError ();
245 if (r
> 0 || error
== WSAENOTCONN
)
246 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
248 /* Distinguish hung-up sockets from other errors. */
249 else if (r
== 0 || error
== WSAESHUTDOWN
|| error
== WSAECONNRESET
250 || error
== WSAECONNABORTED
|| error
== WSAENETRESET
)
257 if (lNetworkEvents
& (FD_WRITE
| FD_CONNECT
))
258 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
260 if (lNetworkEvents
& FD_OOB
)
261 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
268 /* Convert select(2) returned fd_sets into poll(2) revents values. */
270 compute_revents (int fd
, int sought
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*efds
)
273 if (FD_ISSET (fd
, rfds
))
278 # if defined __MACH__ && defined __APPLE__
279 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
280 for some kinds of descriptors. Detect if this descriptor is a
281 connected socket, a server socket, or something else using a
282 0-byte recv, and use ioctl(2) to detect POLLHUP. */
283 r
= recv (fd
, NULL
, 0, MSG_PEEK
);
284 socket_errno
= (r
< 0) ? errno
: 0;
285 if (r
== 0 || socket_errno
== ENOTSOCK
)
286 ioctl (fd
, FIONREAD
, &r
);
289 r
= recv (fd
, data
, sizeof (data
), MSG_PEEK
);
290 socket_errno
= (r
< 0) ? errno
: 0;
295 /* If the event happened on an unconnected server socket,
297 else if (r
> 0 || ( /* (r == -1) && */ socket_errno
== ENOTCONN
))
298 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
300 /* Distinguish hung-up sockets from other errors. */
301 else if (socket_errno
== ESHUTDOWN
|| socket_errno
== ECONNRESET
302 || socket_errno
== ECONNABORTED
|| socket_errno
== ENETRESET
)
309 if (FD_ISSET (fd
, wfds
))
310 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
312 if (FD_ISSET (fd
, efds
))
313 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
320 poll (struct pollfd
*pfd
, nfds_t nfd
, int timeout
)
323 fd_set rfds
, wfds
, efds
;
330 static int sc_open_max
= -1;
333 || (nfd
> sc_open_max
334 && (sc_open_max
!= -1
335 || nfd
> (sc_open_max
= sysconf (_SC_OPEN_MAX
)))))
340 # else /* !_SC_OPEN_MAX */
342 if (nfd
< 0 || nfd
> OPEN_MAX
)
347 # endif /* OPEN_MAX -- else, no check is needed */
348 # endif /* !_SC_OPEN_MAX */
350 /* EFAULT is not necessary to implement, but let's do it in the
358 /* convert timeout number into a timeval structure */
365 else if (timeout
> 0)
368 ptv
->tv_sec
= timeout
/ 1000;
369 ptv
->tv_usec
= (timeout
% 1000) * 1000;
371 else if (timeout
== INFTIM
)
380 /* create fd sets and determine max fd */
385 for (i
= 0; i
< nfd
; i
++)
390 if (pfd
[i
].events
& (POLLIN
| POLLRDNORM
))
391 FD_SET (pfd
[i
].fd
, &rfds
);
393 /* see select(2): "the only exceptional condition detectable
394 is out-of-band data received on a socket", hence we push
395 POLLWRBAND events onto wfds instead of efds. */
396 if (pfd
[i
].events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
397 FD_SET (pfd
[i
].fd
, &wfds
);
398 if (pfd
[i
].events
& (POLLPRI
| POLLRDBAND
))
399 FD_SET (pfd
[i
].fd
, &efds
);
400 if (pfd
[i
].fd
>= maxfd
401 && (pfd
[i
].events
& (POLLIN
| POLLOUT
| POLLPRI
402 | POLLRDNORM
| POLLRDBAND
403 | POLLWRNORM
| POLLWRBAND
)))
406 if (maxfd
> FD_SETSIZE
)
414 /* examine fd sets */
415 rc
= select (maxfd
+ 1, &rfds
, &wfds
, &efds
, ptv
);
419 /* establish results */
421 for (i
= 0; i
< nfd
; i
++)
426 int happened
= compute_revents (pfd
[i
].fd
, pfd
[i
].events
,
427 &rfds
, &wfds
, &efds
);
430 pfd
[i
].revents
= happened
;
437 static struct timeval tv0
;
438 static HANDLE hEvent
;
440 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
441 DWORD ret
, wait_timeout
, nhandles
;
442 fd_set rfds
, wfds
, xfds
;
448 if (nfd
< 0 || timeout
< -1)
455 hEvent
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
458 handle_array
[0] = hEvent
;
464 /* Classify socket handles and create fd sets. */
465 for (i
= 0; i
< nfd
; i
++)
467 int sought
= pfd
[i
].events
;
471 if (!(sought
& (POLLIN
| POLLRDNORM
| POLLOUT
| POLLWRNORM
| POLLWRBAND
472 | POLLPRI
| POLLRDBAND
)))
475 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
477 if (IsSocketHandle (h
))
479 int requested
= FD_CLOSE
;
481 /* see above; socket handles are mapped onto select. */
482 if (sought
& (POLLIN
| POLLRDNORM
))
484 requested
|= FD_READ
| FD_ACCEPT
;
485 FD_SET ((SOCKET
) h
, &rfds
);
487 if (sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
489 requested
|= FD_WRITE
| FD_CONNECT
;
490 FD_SET ((SOCKET
) h
, &wfds
);
492 if (sought
& (POLLPRI
| POLLRDBAND
))
495 FD_SET ((SOCKET
) h
, &xfds
);
499 WSAEventSelect ((SOCKET
) h
, hEvent
, requested
);
503 /* Poll now. If we get an event, do not poll again. Also,
504 screen buffer handles are waitable, and they'll block until
505 a character is available. win32_compute_revents eliminates
506 bits for the "wrong" direction. */
507 pfd
[i
].revents
= win32_compute_revents (h
, &sought
);
509 handle_array
[nhandles
++] = h
;
515 if (select (0, &rfds
, &wfds
, &xfds
, &tv0
) > 0)
517 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
518 no need to call select again. */
525 if (timeout
== INFTIM
)
526 wait_timeout
= INFINITE
;
528 wait_timeout
= timeout
;
533 ret
= MsgWaitForMultipleObjects (nhandles
, handle_array
, FALSE
,
534 wait_timeout
, QS_ALLINPUT
);
536 if (ret
== WAIT_OBJECT_0
+ nhandles
)
538 /* new input of some other kind */
540 while ((bRet
= PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
)) != 0)
542 TranslateMessage (&msg
);
543 DispatchMessage (&msg
);
551 select (0, &rfds
, &wfds
, &xfds
, &tv0
);
553 /* Place a sentinel at the end of the array. */
554 handle_array
[nhandles
] = NULL
;
556 for (i
= 0; i
< nfd
; i
++)
562 if (!(pfd
[i
].events
& (POLLIN
| POLLRDNORM
|
563 POLLOUT
| POLLWRNORM
| POLLWRBAND
)))
566 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
567 if (h
!= handle_array
[nhandles
])
570 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
571 WSAEventSelect ((SOCKET
) h
, 0, 0);
573 /* If we're lucky, WSAEnumNetworkEvents already provided a way
574 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
575 if (FD_ISSET ((SOCKET
) h
, &rfds
)
576 && !(ev
.lNetworkEvents
& (FD_READ
| FD_ACCEPT
)))
577 ev
.lNetworkEvents
|= FD_READ
| FD_ACCEPT
;
578 if (FD_ISSET ((SOCKET
) h
, &wfds
))
579 ev
.lNetworkEvents
|= FD_WRITE
| FD_CONNECT
;
580 if (FD_ISSET ((SOCKET
) h
, &xfds
))
581 ev
.lNetworkEvents
|= FD_OOB
;
583 happened
= win32_compute_revents_socket ((SOCKET
) h
, pfd
[i
].events
,
589 int sought
= pfd
[i
].events
;
590 happened
= win32_compute_revents (h
, &sought
);
594 if ((pfd
[i
].revents
|= happened
) != 0)
598 if (!rc
&& timeout
== INFTIM
)