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, see <http://www.gnu.org/licenses/>. */
21 /* To bump the minimum Windows version to Windows Vista */
22 #include "git-compat-util.h"
24 /* Tell gcc not to warn about the (nfd < 0) tests, below. */
25 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
26 # pragma GCC diagnostic ignored "-Wtype-limits"
33 #include <sys/types.h>
39 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
41 # if defined (_MSC_VER) && !defined(_WIN32_WINNT)
42 # define _WIN32_WINNT 0x0502
44 # include <winsock2.h>
50 # include <sys/time.h>
51 # include <sys/socket.h>
52 # ifndef NO_SYS_SELECT_H
53 # include <sys/select.h>
61 #ifdef HAVE_SYS_IOCTL_H
62 # include <sys/ioctl.h>
64 #ifdef HAVE_SYS_FILIO_H
65 # include <sys/filio.h>
74 /* BeOS does not have MSG_PEEK. */
81 #define IsConsoleHandle(h) (((long) (intptr_t) (h) & 3) == 3)
84 IsSocketHandle (HANDLE h
)
88 if (IsConsoleHandle (h
))
91 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
92 WSAEnumNetworkEvents instead distinguishes the two correctly. */
93 ev
.lNetworkEvents
= 0xDEADBEEF;
94 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
95 return ev
.lNetworkEvents
!= 0xDEADBEEF;
98 /* Declare data structures for ntdll functions. */
99 typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
101 ULONG NamedPipeConfiguration
;
102 ULONG MaximumInstances
;
103 ULONG CurrentInstances
;
105 ULONG ReadDataAvailable
;
107 ULONG WriteQuotaAvailable
;
108 ULONG NamedPipeState
;
110 } FILE_PIPE_LOCAL_INFORMATION
, *PFILE_PIPE_LOCAL_INFORMATION
;
112 typedef struct _IO_STATUS_BLOCK
118 ULONG_PTR Information
;
119 } IO_STATUS_BLOCK
, *PIO_STATUS_BLOCK
;
121 typedef enum _FILE_INFORMATION_CLASS
{
122 FilePipeLocalInformation
= 24
123 } FILE_INFORMATION_CLASS
, *PFILE_INFORMATION_CLASS
;
125 typedef DWORD (WINAPI
*PNtQueryInformationFile
)
126 (HANDLE
, IO_STATUS_BLOCK
*, VOID
*, ULONG
, FILE_INFORMATION_CLASS
);
129 # define PIPE_BUF 512
132 /* Compute revents values for file handle H. If some events cannot happen
133 for the handle, eliminate them from *P_SOUGHT. */
136 win32_compute_revents (HANDLE h
, int *p_sought
)
138 int i
, ret
, happened
;
139 INPUT_RECORD
*irbuffer
;
140 DWORD avail
, nbuffer
;
143 switch (GetFileType (h
))
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. Unfortunately there is no
158 reliable way of knowing if it can be written without blocking.
159 Just say that it's all good. */
160 happened
|= *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
165 ret
= WaitForSingleObject (h
, 0);
166 if (!IsConsoleHandle (h
))
167 return ret
== WAIT_OBJECT_0
? *p_sought
& ~(POLLPRI
| POLLRDBAND
) : 0;
170 bRet
= GetNumberOfConsoleInputEvents (h
, &nbuffer
);
174 *p_sought
&= POLLIN
| POLLRDNORM
;
180 irbuffer
= (INPUT_RECORD
*) alloca (nbuffer
* sizeof (INPUT_RECORD
));
181 bRet
= PeekConsoleInput (h
, irbuffer
, nbuffer
, &avail
);
182 if (!bRet
|| avail
== 0)
185 for (i
= 0; i
< avail
; i
++)
186 if (irbuffer
[i
].EventType
== KEY_EVENT
)
193 *p_sought
&= POLLOUT
| POLLWRNORM
| POLLWRBAND
;
198 ret
= WaitForSingleObject (h
, 0);
199 if (ret
== WAIT_OBJECT_0
)
200 return *p_sought
& ~(POLLPRI
| POLLRDBAND
);
202 return *p_sought
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
206 /* Convert fd_sets returned by select into revents values. */
209 win32_compute_revents_socket (SOCKET h
, int sought
, long lNetworkEvents
)
213 if ((lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
)) == FD_ACCEPT
)
214 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
216 else if (lNetworkEvents
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
))
222 r
= recv (h
, data
, sizeof (data
), MSG_PEEK
);
223 error
= WSAGetLastError ();
226 if (r
> 0 || error
== WSAENOTCONN
)
227 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
229 /* Distinguish hung-up sockets from other errors. */
230 else if (r
== 0 || error
== WSAESHUTDOWN
|| error
== WSAECONNRESET
231 || error
== WSAECONNABORTED
|| error
== WSAENETRESET
)
238 if (lNetworkEvents
& (FD_WRITE
| FD_CONNECT
))
239 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
241 if (lNetworkEvents
& FD_OOB
)
242 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
249 /* Convert select(2) returned fd_sets into poll(2) revents values. */
251 compute_revents (int fd
, int sought
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*efds
)
254 if (FD_ISSET (fd
, rfds
))
259 # if defined __MACH__ && defined __APPLE__
260 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
261 for some kinds of descriptors. Detect if this descriptor is a
262 connected socket, a server socket, or something else using a
263 0-byte recv, and use ioctl(2) to detect POLLHUP. */
264 r
= recv (fd
, NULL
, 0, MSG_PEEK
);
265 socket_errno
= (r
< 0) ? errno
: 0;
266 if (r
== 0 || socket_errno
== ENOTSOCK
)
267 ioctl (fd
, FIONREAD
, &r
);
270 r
= recv (fd
, data
, sizeof (data
), MSG_PEEK
);
271 socket_errno
= (r
< 0) ? errno
: 0;
276 /* If the event happened on an unconnected server socket,
278 else if (r
> 0 || ( /* (r == -1) && */ socket_errno
== ENOTCONN
))
279 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
281 /* Distinguish hung-up sockets from other errors. */
282 else if (socket_errno
== ESHUTDOWN
|| socket_errno
== ECONNRESET
283 || socket_errno
== ECONNABORTED
|| socket_errno
== ENETRESET
)
286 /* some systems can't use recv() on non-socket, including HP NonStop */
287 else if (/* (r == -1) && */ socket_errno
== ENOTSOCK
)
288 happened
|= (POLLIN
| POLLRDNORM
) & sought
;
294 if (FD_ISSET (fd
, wfds
))
295 happened
|= (POLLOUT
| POLLWRNORM
| POLLWRBAND
) & sought
;
297 if (FD_ISSET (fd
, efds
))
298 happened
|= (POLLPRI
| POLLRDBAND
) & sought
;
305 poll (struct pollfd
*pfd
, nfds_t nfd
, int timeout
)
308 fd_set rfds
, wfds
, efds
;
315 static int sc_open_max
= -1;
318 || (nfd
> sc_open_max
319 && (sc_open_max
!= -1
320 || nfd
> (sc_open_max
= sysconf (_SC_OPEN_MAX
)))))
325 # else /* !_SC_OPEN_MAX */
327 if (nfd
< 0 || nfd
> OPEN_MAX
)
332 # endif /* OPEN_MAX -- else, no check is needed */
333 # endif /* !_SC_OPEN_MAX */
335 /* EFAULT is not necessary to implement, but let's do it in the
343 /* convert timeout number into a timeval structure */
350 else if (timeout
> 0)
353 ptv
->tv_sec
= timeout
/ 1000;
354 ptv
->tv_usec
= (timeout
% 1000) * 1000;
356 else if (timeout
== INFTIM
)
365 /* create fd sets and determine max fd */
370 for (i
= 0; i
< nfd
; i
++)
375 if (pfd
[i
].events
& (POLLIN
| POLLRDNORM
))
376 FD_SET (pfd
[i
].fd
, &rfds
);
378 /* see select(2): "the only exceptional condition detectable
379 is out-of-band data received on a socket", hence we push
380 POLLWRBAND events onto wfds instead of efds. */
381 if (pfd
[i
].events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
))
382 FD_SET (pfd
[i
].fd
, &wfds
);
383 if (pfd
[i
].events
& (POLLPRI
| POLLRDBAND
))
384 FD_SET (pfd
[i
].fd
, &efds
);
385 if (pfd
[i
].fd
>= maxfd
386 && (pfd
[i
].events
& (POLLIN
| POLLOUT
| POLLPRI
387 | POLLRDNORM
| POLLRDBAND
388 | POLLWRNORM
| POLLWRBAND
)))
391 if (maxfd
> FD_SETSIZE
)
399 /* examine fd sets */
400 rc
= select (maxfd
+ 1, &rfds
, &wfds
, &efds
, ptv
);
404 /* establish results */
406 for (i
= 0; i
< nfd
; i
++)
411 int happened
= compute_revents (pfd
[i
].fd
, pfd
[i
].events
,
412 &rfds
, &wfds
, &efds
);
415 pfd
[i
].revents
= happened
;
426 static struct timeval tv0
;
427 static HANDLE hEvent
;
429 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
430 DWORD ret
, wait_timeout
, nhandles
, orig_timeout
= 0;
432 fd_set rfds
, wfds
, xfds
;
438 if (nfd
< 0 || timeout
< -1)
444 if (timeout
!= INFTIM
)
446 orig_timeout
= timeout
;
447 start
= GetTickCount64();
451 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
, NULL
, 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)
594 if (!rc
&& orig_timeout
&& timeout
!= INFTIM
)
596 ULONGLONG elapsed
= GetTickCount64() - start
;
597 timeout
= elapsed
>= orig_timeout
? 0 : (int)(orig_timeout
- elapsed
);