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
)
313 if (FD_ISSET (fd
, wfds
))
314 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
316 if (FD_ISSET (fd
, efds
))
317 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
324 poll (struct pollfd
*pfd
, nfds_t nfd
, int timeout
)
327 fd_set rfds
, wfds
, efds
;
334 static int sc_open_max
= -1;
337 || (nfd
> sc_open_max
338 && (sc_open_max
!= -1
339 || nfd
> (sc_open_max
= sysconf (_SC_OPEN_MAX
)))))
344 # else /* !_SC_OPEN_MAX */
346 if (nfd
< 0 || nfd
> OPEN_MAX
)
351 # endif /* OPEN_MAX -- else, no check is needed */
352 # endif /* !_SC_OPEN_MAX */
354 /* EFAULT is not necessary to implement, but let's do it in the
362 /* convert timeout number into a timeval structure */
369 else if (timeout
> 0)
372 ptv
->tv_sec
= timeout
/ 1000;
373 ptv
->tv_usec
= (timeout
% 1000) * 1000;
375 else if (timeout
== INFTIM
)
384 /* create fd sets and determine max fd */
389 for (i
= 0; i
< nfd
; i
++)
394 if (pfd
[i
].events
& (POLLIN
| POLLRDNORM
))
395 FD_SET (pfd
[i
].fd
, &rfds
);
397 /* see select(2): "the only exceptional condition detectable
398 is out-of-band data received on a socket", hence we push
399 POLLWRBAND events onto wfds instead of efds. */
400 if (pfd
[i
].events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
401 FD_SET (pfd
[i
].fd
, &wfds
);
402 if (pfd
[i
].events
& (POLLPRI
| POLLRDBAND
))
403 FD_SET (pfd
[i
].fd
, &efds
);
404 if (pfd
[i
].fd
>= maxfd
405 && (pfd
[i
].events
& (POLLIN
| POLLOUT
| POLLPRI
406 | POLLRDNORM
| POLLRDBAND
407 | POLLWRNORM
| POLLWRBAND
)))
410 if (maxfd
> FD_SETSIZE
)
418 /* examine fd sets */
419 rc
= select (maxfd
+ 1, &rfds
, &wfds
, &efds
, ptv
);
423 /* establish results */
425 for (i
= 0; i
< nfd
; i
++)
430 int happened
= compute_revents (pfd
[i
].fd
, pfd
[i
].events
,
431 &rfds
, &wfds
, &efds
);
434 pfd
[i
].revents
= happened
;
441 static struct timeval tv0
;
442 static HANDLE hEvent
;
444 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
445 DWORD ret
, wait_timeout
, nhandles
;
446 fd_set rfds
, wfds
, xfds
;
452 if (nfd
< 0 || timeout
< -1)
459 hEvent
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
462 handle_array
[0] = hEvent
;
468 /* Classify socket handles and create fd sets. */
469 for (i
= 0; i
< nfd
; i
++)
471 int sought
= pfd
[i
].events
;
475 if (!(sought
& (POLLIN
| POLLRDNORM
| POLLOUT
| POLLWRNORM
| POLLWRBAND
476 | POLLPRI
| POLLRDBAND
)))
479 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
481 if (IsSocketHandle (h
))
483 int requested
= FD_CLOSE
;
485 /* see above; socket handles are mapped onto select. */
486 if (sought
& (POLLIN
| POLLRDNORM
))
488 requested
|= FD_READ
| FD_ACCEPT
;
489 FD_SET ((SOCKET
) h
, &rfds
);
491 if (sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
493 requested
|= FD_WRITE
| FD_CONNECT
;
494 FD_SET ((SOCKET
) h
, &wfds
);
496 if (sought
& (POLLPRI
| POLLRDBAND
))
499 FD_SET ((SOCKET
) h
, &xfds
);
503 WSAEventSelect ((SOCKET
) h
, hEvent
, requested
);
507 /* Poll now. If we get an event, do not poll again. Also,
508 screen buffer handles are waitable, and they'll block until
509 a character is available. win32_compute_revents eliminates
510 bits for the "wrong" direction. */
511 pfd
[i
].revents
= win32_compute_revents (h
, &sought
);
513 handle_array
[nhandles
++] = h
;
519 if (select (0, &rfds
, &wfds
, &xfds
, &tv0
) > 0)
521 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
522 no need to call select again. */
529 if (timeout
== INFTIM
)
530 wait_timeout
= INFINITE
;
532 wait_timeout
= timeout
;
537 ret
= MsgWaitForMultipleObjects (nhandles
, handle_array
, FALSE
,
538 wait_timeout
, QS_ALLINPUT
);
540 if (ret
== WAIT_OBJECT_0
+ nhandles
)
542 /* new input of some other kind */
544 while ((bRet
= PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
)) != 0)
546 TranslateMessage (&msg
);
547 DispatchMessage (&msg
);
555 select (0, &rfds
, &wfds
, &xfds
, &tv0
);
557 /* Place a sentinel at the end of the array. */
558 handle_array
[nhandles
] = NULL
;
560 for (i
= 0; i
< nfd
; i
++)
566 if (!(pfd
[i
].events
& (POLLIN
| POLLRDNORM
|
567 POLLOUT
| POLLWRNORM
| POLLWRBAND
)))
570 h
= (HANDLE
) _get_osfhandle (pfd
[i
].fd
);
571 if (h
!= handle_array
[nhandles
])
574 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
575 WSAEventSelect ((SOCKET
) h
, 0, 0);
577 /* If we're lucky, WSAEnumNetworkEvents already provided a way
578 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
579 if (FD_ISSET ((SOCKET
) h
, &rfds
)
580 && !(ev
.lNetworkEvents
& (FD_READ
| FD_ACCEPT
)))
581 ev
.lNetworkEvents
|= FD_READ
| FD_ACCEPT
;
582 if (FD_ISSET ((SOCKET
) h
, &wfds
))
583 ev
.lNetworkEvents
|= FD_WRITE
| FD_CONNECT
;
584 if (FD_ISSET ((SOCKET
) h
, &xfds
))
585 ev
.lNetworkEvents
|= FD_OOB
;
587 happened
= win32_compute_revents_socket ((SOCKET
) h
, pfd
[i
].events
,
593 int sought
= pfd
[i
].events
;
594 happened
= win32_compute_revents (h
, &sought
);
598 if ((pfd
[i
].revents
|= happened
) != 0)
602 if (!rc
&& timeout
== INFTIM
)