1 /* Emulation for select(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2008-2017 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/>. */
25 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
28 #include <sys/types.h>
39 /* Get the overridden 'struct timeval'. */
42 #if GNULIB_MSVC_NOTHROW
43 # include "msvc-nothrow.h"
51 unsigned char in
[FD_SETSIZE
/ CHAR_BIT
];
52 unsigned char out
[FD_SETSIZE
/ CHAR_BIT
];
55 /* Declare data structures for ntdll functions. */
56 typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
58 ULONG NamedPipeConfiguration
;
59 ULONG MaximumInstances
;
60 ULONG CurrentInstances
;
62 ULONG ReadDataAvailable
;
64 ULONG WriteQuotaAvailable
;
67 } FILE_PIPE_LOCAL_INFORMATION
, *PFILE_PIPE_LOCAL_INFORMATION
;
69 typedef struct _IO_STATUS_BLOCK
75 ULONG_PTR Information
;
76 } IO_STATUS_BLOCK
, *PIO_STATUS_BLOCK
;
78 typedef enum _FILE_INFORMATION_CLASS
{
79 FilePipeLocalInformation
= 24
80 } FILE_INFORMATION_CLASS
, *PFILE_INFORMATION_CLASS
;
82 typedef DWORD (WINAPI
*PNtQueryInformationFile
)
83 (HANDLE
, IO_STATUS_BLOCK
*, VOID
*, ULONG
, FILE_INFORMATION_CLASS
);
89 static BOOL
IsConsoleHandle (HANDLE h
)
92 return GetConsoleMode (h
, &mode
) != 0;
96 IsSocketHandle (HANDLE h
)
100 if (IsConsoleHandle (h
))
103 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
104 WSAEnumNetworkEvents instead distinguishes the two correctly. */
105 ev
.lNetworkEvents
= 0xDEADBEEF;
106 WSAEnumNetworkEvents ((SOCKET
) h
, NULL
, &ev
);
107 return ev
.lNetworkEvents
!= 0xDEADBEEF;
110 /* Compute output fd_sets for libc descriptor FD (whose Windows handle is
114 windows_poll_handle (HANDLE h
, int fd
,
115 struct bitset
*rbits
,
116 struct bitset
*wbits
,
117 struct bitset
*xbits
)
119 BOOL read
, write
, except
;
121 INPUT_RECORD
*irbuffer
;
122 DWORD avail
, nbuffer
;
124 IO_STATUS_BLOCK iosb
;
125 FILE_PIPE_LOCAL_INFORMATION fpli
;
126 static PNtQueryInformationFile NtQueryInformationFile
;
127 static BOOL once_only
;
129 read
= write
= except
= FALSE
;
130 switch (GetFileType (h
))
140 NtQueryInformationFile
= (PNtQueryInformationFile
)
141 GetProcAddress (GetModuleHandle ("ntdll.dll"),
142 "NtQueryInformationFile");
146 if (PeekNamedPipe (h
, NULL
, 0, NULL
, &avail
, NULL
) != 0)
151 else if (GetLastError () == ERROR_BROKEN_PIPE
)
156 /* It was the write-end of the pipe. Check if it is writable.
157 If NtQueryInformationFile fails, optimistically assume the pipe is
158 writable. This could happen on Windows 9x, where
159 NtQueryInformationFile is not available, or if we inherit a pipe
160 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
161 (I think this should not happen since Windows XP SP2; WINE seems
162 fine too). Otherwise, ensure that enough space is available for
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
))
179 if (!(rbits
->in
[fd
/ CHAR_BIT
] & (1 << (fd
& (CHAR_BIT
- 1)))))
182 ret
= WaitForSingleObject (h
, 0);
183 if (ret
== WAIT_OBJECT_0
)
185 if (!IsConsoleHandle (h
))
192 bRet
= GetNumberOfConsoleInputEvents (h
, &nbuffer
);
194 /* Screen buffers handles are filtered earlier. */
202 irbuffer
= (INPUT_RECORD
*) alloca (nbuffer
* sizeof (INPUT_RECORD
));
203 bRet
= PeekConsoleInput (h
, irbuffer
, nbuffer
, &avail
);
204 if (!bRet
|| avail
== 0)
210 for (i
= 0; i
< avail
; i
++)
211 if (irbuffer
[i
].EventType
== KEY_EVENT
)
217 ret
= WaitForSingleObject (h
, 0);
219 if (ret
== WAIT_OBJECT_0
)
226 if (read
&& (rbits
->in
[fd
/ CHAR_BIT
] & (1 << (fd
& (CHAR_BIT
- 1)))))
228 rbits
->out
[fd
/ CHAR_BIT
] |= (1 << (fd
& (CHAR_BIT
- 1)));
232 if (write
&& (wbits
->in
[fd
/ CHAR_BIT
] & (1 << (fd
& (CHAR_BIT
- 1)))))
234 wbits
->out
[fd
/ CHAR_BIT
] |= (1 << (fd
& (CHAR_BIT
- 1)));
238 if (except
&& (xbits
->in
[fd
/ CHAR_BIT
] & (1 << (fd
& (CHAR_BIT
- 1)))))
240 xbits
->out
[fd
/ CHAR_BIT
] |= (1 << (fd
& (CHAR_BIT
- 1)));
248 rpl_select (int nfds
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*xfds
,
249 struct timeval
*timeout
)
252 static struct timeval tv0
;
253 static HANDLE hEvent
;
254 HANDLE h
, handle_array
[FD_SETSIZE
+ 2];
255 fd_set handle_rfds
, handle_wfds
, handle_xfds
;
256 struct bitset rbits
, wbits
, xbits
;
257 unsigned char anyfds_in
[FD_SETSIZE
/ CHAR_BIT
];
258 DWORD ret
, wait_timeout
, nhandles
, nsock
, nbuffer
;
263 if (nfds
> FD_SETSIZE
)
267 wait_timeout
= INFINITE
;
270 wait_timeout
= timeout
->tv_sec
* 1000 + timeout
->tv_usec
/ 1000;
272 /* select is also used as a portable usleep. */
273 if (!rfds
&& !wfds
&& !xfds
)
275 Sleep (wait_timeout
);
281 hEvent
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
283 handle_array
[0] = hEvent
;
287 /* Copy descriptors to bitsets. At the same time, eliminate
288 bits in the "wrong" direction for console input buffers
289 and screen buffers, because screen buffers are waitable
290 and they will block until a character is available. */
291 memset (&rbits
, 0, sizeof (rbits
));
292 memset (&wbits
, 0, sizeof (wbits
));
293 memset (&xbits
, 0, sizeof (xbits
));
294 memset (anyfds_in
, 0, sizeof (anyfds_in
));
296 for (i
= 0; i
< rfds
->fd_count
; i
++)
298 fd
= rfds
->fd_array
[i
];
299 h
= (HANDLE
) _get_osfhandle (fd
);
300 if (IsConsoleHandle (h
)
301 && !GetNumberOfConsoleInputEvents (h
, &nbuffer
))
304 rbits
.in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
305 anyfds_in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
308 rfds
= (fd_set
*) alloca (sizeof (fd_set
));
311 for (i
= 0; i
< wfds
->fd_count
; i
++)
313 fd
= wfds
->fd_array
[i
];
314 h
= (HANDLE
) _get_osfhandle (fd
);
315 if (IsConsoleHandle (h
)
316 && GetNumberOfConsoleInputEvents (h
, &nbuffer
))
319 wbits
.in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
320 anyfds_in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
323 wfds
= (fd_set
*) alloca (sizeof (fd_set
));
326 for (i
= 0; i
< xfds
->fd_count
; i
++)
328 fd
= xfds
->fd_array
[i
];
329 xbits
.in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
330 anyfds_in
[fd
/ CHAR_BIT
] |= 1 << (fd
& (CHAR_BIT
- 1));
333 xfds
= (fd_set
*) alloca (sizeof (fd_set
));
335 /* Zero all the fd_sets, including the application's. */
339 FD_ZERO (&handle_rfds
);
340 FD_ZERO (&handle_wfds
);
341 FD_ZERO (&handle_xfds
);
343 /* Classify handles. Create fd sets for sockets, poll the others. */
344 for (i
= 0; i
< nfds
; i
++)
346 if ((anyfds_in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1)))) == 0)
349 h
= (HANDLE
) _get_osfhandle (i
);
356 if (IsSocketHandle (h
))
358 int requested
= FD_CLOSE
;
360 /* See above; socket handles are mapped onto select, but we
361 need to map descriptors to handles. */
362 if (rbits
.in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
364 requested
|= FD_READ
| FD_ACCEPT
;
365 FD_SET ((SOCKET
) h
, rfds
);
366 FD_SET ((SOCKET
) h
, &handle_rfds
);
368 if (wbits
.in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
370 requested
|= FD_WRITE
| FD_CONNECT
;
371 FD_SET ((SOCKET
) h
, wfds
);
372 FD_SET ((SOCKET
) h
, &handle_wfds
);
374 if (xbits
.in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
377 FD_SET ((SOCKET
) h
, xfds
);
378 FD_SET ((SOCKET
) h
, &handle_xfds
);
381 WSAEventSelect ((SOCKET
) h
, hEvent
, requested
);
386 handle_array
[nhandles
++] = h
;
388 /* Poll now. If we get an event, do not wait below. */
389 if (wait_timeout
!= 0
390 && windows_poll_handle (h
, i
, &rbits
, &wbits
, &xbits
))
395 /* Place a sentinel at the end of the array. */
396 handle_array
[nhandles
] = NULL
;
398 /* When will the waiting period expire? */
399 if (wait_timeout
!= INFINITE
)
400 tend
= clock () + wait_timeout
;
403 if (wait_timeout
== 0 || nsock
== 0)
407 /* See if we need to wait in the loop below. If any select is ready,
408 do MsgWaitForMultipleObjects anyway to dispatch messages, but
409 no need to call select again. */
410 rc
= select (0, &handle_rfds
, &handle_wfds
, &handle_xfds
, &tv0
);
413 /* Restore the fd_sets for the other select we do below. */
414 memcpy (&handle_rfds
, rfds
, sizeof (fd_set
));
415 memcpy (&handle_wfds
, wfds
, sizeof (fd_set
));
416 memcpy (&handle_xfds
, xfds
, sizeof (fd_set
));
422 /* How much is left to wait? */
423 if (wait_timeout
!= INFINITE
)
425 clock_t tnow
= clock ();
427 wait_timeout
= tend
- tnow
;
434 ret
= MsgWaitForMultipleObjects (nhandles
, handle_array
, FALSE
,
435 wait_timeout
, QS_ALLINPUT
);
437 if (ret
== WAIT_OBJECT_0
+ nhandles
)
439 /* new input of some other kind */
441 while ((bRet
= PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
)) != 0)
443 TranslateMessage (&msg
);
444 DispatchMessage (&msg
);
451 /* If we haven't done it yet, check the status of the sockets. */
452 if (rc
== 0 && nsock
> 0)
453 rc
= select (0, &handle_rfds
, &handle_wfds
, &handle_xfds
, &tv0
);
457 /* Count results that are not counted in the return value of select. */
459 for (i
= 0; i
< nfds
; i
++)
461 if ((anyfds_in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1)))) == 0)
464 h
= (HANDLE
) _get_osfhandle (i
);
465 if (h
== handle_array
[nhandles
])
469 windows_poll_handle (h
, i
, &rbits
, &wbits
, &xbits
);
470 if (rbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1)))
471 || wbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1)))
472 || xbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
478 && (wait_timeout
== INFINITE
479 /* If NHANDLES > 1, but no bits are set, it means we've
480 been told incorrectly that some handle was signaled.
481 This happens with anonymous pipes, which always cause
482 MsgWaitForMultipleObjects to exit immediately, but no
483 data is found ready to be read by windows_poll_handle.
484 To avoid a total failure (whereby we return zero and
485 don't wait at all), let's poll in a more busy loop. */
486 || (wait_timeout
!= 0 && nhandles
> 1)))
488 /* Sleep 1 millisecond to avoid busy wait and retry with the
490 memcpy (&handle_rfds
, rfds
, sizeof (fd_set
));
491 memcpy (&handle_wfds
, wfds
, sizeof (fd_set
));
492 memcpy (&handle_xfds
, xfds
, sizeof (fd_set
));
496 if (timeout
&& wait_timeout
== 0 && rc
== 0)
497 timeout
->tv_sec
= timeout
->tv_usec
= 0;
500 /* Now fill in the results. */
505 for (i
= 0; i
< nfds
; i
++)
507 if ((anyfds_in
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1)))) == 0)
510 h
= (HANDLE
) _get_osfhandle (i
);
511 if (h
!= handle_array
[nhandles
])
513 /* Perform handle->descriptor mapping. */
514 WSAEventSelect ((SOCKET
) h
, NULL
, 0);
515 if (FD_ISSET (h
, &handle_rfds
))
517 if (FD_ISSET (h
, &handle_wfds
))
519 if (FD_ISSET (h
, &handle_xfds
))
526 if (rbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
528 if (wbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
530 if (xbits
.out
[i
/ CHAR_BIT
] & (1 << (i
& (CHAR_BIT
- 1))))
538 #else /* ! Native Windows. */
540 #include <sys/select.h>
541 #include <stddef.h> /* NULL */
548 rpl_select (int nfds
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*xfds
,
549 struct timeval
*timeout
)
553 /* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */
554 if (nfds
< 0 || nfds
> FD_SETSIZE
)
559 for (i
= 0; i
< nfds
; i
++)
561 if (((rfds
&& FD_ISSET (i
, rfds
))
562 || (wfds
&& FD_ISSET (i
, wfds
))
563 || (xfds
&& FD_ISSET (i
, xfds
)))
568 /* Interix 3.5 has a bug: it does not support nfds == 0. */
576 return select (nfds
, rfds
, wfds
, xfds
, timeout
);