1 /* Emulation for select(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2008-2016 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 #include "msvc-nothrow.h"
47 unsigned char in[FD_SETSIZE / CHAR_BIT];
48 unsigned char out[FD_SETSIZE / CHAR_BIT];
51 /* Declare data structures for ntdll functions. */
52 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
54 ULONG NamedPipeConfiguration;
55 ULONG MaximumInstances;
56 ULONG CurrentInstances;
58 ULONG ReadDataAvailable;
60 ULONG WriteQuotaAvailable;
63 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
65 typedef struct _IO_STATUS_BLOCK
71 ULONG_PTR Information;
72 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
74 typedef enum _FILE_INFORMATION_CLASS {
75 FilePipeLocalInformation = 24
76 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
78 typedef DWORD (WINAPI *PNtQueryInformationFile)
79 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
85 static BOOL IsConsoleHandle (HANDLE h)
88 return GetConsoleMode (h, &mode) != 0;
92 IsSocketHandle (HANDLE h)
96 if (IsConsoleHandle (h))
99 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
100 WSAEnumNetworkEvents instead distinguishes the two correctly. */
101 ev.lNetworkEvents = 0xDEADBEEF;
102 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
103 return ev.lNetworkEvents != 0xDEADBEEF;
106 /* Compute output fd_sets for libc descriptor FD (whose Windows handle is
110 windows_poll_handle (HANDLE h, int fd,
111 struct bitset *rbits,
112 struct bitset *wbits,
113 struct bitset *xbits)
115 BOOL read, write, except;
117 INPUT_RECORD *irbuffer;
118 DWORD avail, nbuffer;
120 IO_STATUS_BLOCK iosb;
121 FILE_PIPE_LOCAL_INFORMATION fpli;
122 static PNtQueryInformationFile NtQueryInformationFile;
123 static BOOL once_only;
125 read = write = except = FALSE;
126 switch (GetFileType (h))
136 NtQueryInformationFile = (PNtQueryInformationFile)
137 GetProcAddress (GetModuleHandle ("ntdll.dll"),
138 "NtQueryInformationFile");
142 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
147 else if (GetLastError () == ERROR_BROKEN_PIPE)
152 /* It was the write-end of the pipe. Check if it is writable.
153 If NtQueryInformationFile fails, optimistically assume the pipe is
154 writable. This could happen on Windows 9x, where
155 NtQueryInformationFile is not available, or if we inherit a pipe
156 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
157 (I think this should not happen since Windows XP SP2; WINE seems
158 fine too). Otherwise, ensure that enough space is available for
160 memset (&iosb, 0, sizeof (iosb));
161 memset (&fpli, 0, sizeof (fpli));
163 if (!NtQueryInformationFile
164 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
165 FilePipeLocalInformation)
166 || fpli.WriteQuotaAvailable >= PIPE_BUF
167 || (fpli.OutboundQuota < PIPE_BUF &&
168 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
175 if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
178 ret = WaitForSingleObject (h, 0);
179 if (ret == WAIT_OBJECT_0)
181 if (!IsConsoleHandle (h))
188 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
190 /* Screen buffers handles are filtered earlier. */
198 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
199 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
200 if (!bRet || avail == 0)
206 for (i = 0; i < avail; i++)
207 if (irbuffer[i].EventType == KEY_EVENT)
213 ret = WaitForSingleObject (h, 0);
215 if (ret == WAIT_OBJECT_0)
222 if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
224 rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
228 if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
230 wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
234 if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
236 xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
244 rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
245 struct timeval *timeout)
248 static struct timeval tv0;
249 static HANDLE hEvent;
250 HANDLE h, handle_array[FD_SETSIZE + 2];
251 fd_set handle_rfds, handle_wfds, handle_xfds;
252 struct bitset rbits, wbits, xbits;
253 unsigned char anyfds_in[FD_SETSIZE / CHAR_BIT];
254 DWORD ret, wait_timeout, nhandles, nsock, nbuffer;
259 if (nfds > FD_SETSIZE)
263 wait_timeout = INFINITE;
266 wait_timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
268 /* select is also used as a portable usleep. */
269 if (!rfds && !wfds && !xfds)
271 Sleep (wait_timeout);
277 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
279 handle_array[0] = hEvent;
283 /* Copy descriptors to bitsets. At the same time, eliminate
284 bits in the "wrong" direction for console input buffers
285 and screen buffers, because screen buffers are waitable
286 and they will block until a character is available. */
287 memset (&rbits, 0, sizeof (rbits));
288 memset (&wbits, 0, sizeof (wbits));
289 memset (&xbits, 0, sizeof (xbits));
290 memset (anyfds_in, 0, sizeof (anyfds_in));
292 for (i = 0; i < rfds->fd_count; i++)
294 fd = rfds->fd_array[i];
295 h = (HANDLE) _get_osfhandle (fd);
296 if (IsConsoleHandle (h)
297 && !GetNumberOfConsoleInputEvents (h, &nbuffer))
300 rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
301 anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
304 rfds = (fd_set *) alloca (sizeof (fd_set));
307 for (i = 0; i < wfds->fd_count; i++)
309 fd = wfds->fd_array[i];
310 h = (HANDLE) _get_osfhandle (fd);
311 if (IsConsoleHandle (h)
312 && GetNumberOfConsoleInputEvents (h, &nbuffer))
315 wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
316 anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
319 wfds = (fd_set *) alloca (sizeof (fd_set));
322 for (i = 0; i < xfds->fd_count; i++)
324 fd = xfds->fd_array[i];
325 xbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
326 anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
329 xfds = (fd_set *) alloca (sizeof (fd_set));
331 /* Zero all the fd_sets, including the application's. */
335 FD_ZERO (&handle_rfds);
336 FD_ZERO (&handle_wfds);
337 FD_ZERO (&handle_xfds);
339 /* Classify handles. Create fd sets for sockets, poll the others. */
340 for (i = 0; i < nfds; i++)
342 if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
345 h = (HANDLE) _get_osfhandle (i);
352 if (IsSocketHandle (h))
354 int requested = FD_CLOSE;
356 /* See above; socket handles are mapped onto select, but we
357 need to map descriptors to handles. */
358 if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
360 requested |= FD_READ | FD_ACCEPT;
361 FD_SET ((SOCKET) h, rfds);
362 FD_SET ((SOCKET) h, &handle_rfds);
364 if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
366 requested |= FD_WRITE | FD_CONNECT;
367 FD_SET ((SOCKET) h, wfds);
368 FD_SET ((SOCKET) h, &handle_wfds);
370 if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
373 FD_SET ((SOCKET) h, xfds);
374 FD_SET ((SOCKET) h, &handle_xfds);
377 WSAEventSelect ((SOCKET) h, hEvent, requested);
382 handle_array[nhandles++] = h;
384 /* Poll now. If we get an event, do not wait below. */
385 if (wait_timeout != 0
386 && windows_poll_handle (h, i, &rbits, &wbits, &xbits))
391 /* Place a sentinel at the end of the array. */
392 handle_array[nhandles] = NULL;
394 /* When will the waiting period expire? */
395 if (wait_timeout != INFINITE)
396 tend = clock () + wait_timeout;
399 if (wait_timeout == 0 || nsock == 0)
403 /* See if we need to wait in the loop below. If any select is ready,
404 do MsgWaitForMultipleObjects anyway to dispatch messages, but
405 no need to call select again. */
406 rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
409 /* Restore the fd_sets for the other select we do below. */
410 memcpy (&handle_rfds, rfds, sizeof (fd_set));
411 memcpy (&handle_wfds, wfds, sizeof (fd_set));
412 memcpy (&handle_xfds, xfds, sizeof (fd_set));
418 /* How much is left to wait? */
419 if (wait_timeout != INFINITE)
421 clock_t tnow = clock ();
423 wait_timeout = tend - tnow;
430 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
431 wait_timeout, QS_ALLINPUT);
433 if (ret == WAIT_OBJECT_0 + nhandles)
435 /* new input of some other kind */
437 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
439 TranslateMessage (&msg);
440 DispatchMessage (&msg);
447 /* If we haven't done it yet, check the status of the sockets. */
448 if (rc == 0 && nsock > 0)
449 rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
453 /* Count results that are not counted in the return value of select. */
455 for (i = 0; i < nfds; i++)
457 if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
460 h = (HANDLE) _get_osfhandle (i);
461 if (h == handle_array[nhandles])
465 windows_poll_handle (h, i, &rbits, &wbits, &xbits);
466 if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
467 || wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
468 || xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
474 && (wait_timeout == INFINITE
475 /* If NHANDLES > 1, but no bits are set, it means we've
476 been told incorrectly that some handle was signaled.
477 This happens with anonymous pipes, which always cause
478 MsgWaitForMultipleObjects to exit immediately, but no
479 data is found ready to be read by windows_poll_handle.
480 To avoid a total failure (whereby we return zero and
481 don't wait at all), let's poll in a more busy loop. */
482 || (wait_timeout != 0 && nhandles > 1)))
484 /* Sleep 1 millisecond to avoid busy wait and retry with the
486 memcpy (&handle_rfds, rfds, sizeof (fd_set));
487 memcpy (&handle_wfds, wfds, sizeof (fd_set));
488 memcpy (&handle_xfds, xfds, sizeof (fd_set));
492 if (timeout && wait_timeout == 0 && rc == 0)
493 timeout->tv_sec = timeout->tv_usec = 0;
496 /* Now fill in the results. */
501 for (i = 0; i < nfds; i++)
503 if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
506 h = (HANDLE) _get_osfhandle (i);
507 if (h != handle_array[nhandles])
509 /* Perform handle->descriptor mapping. */
510 WSAEventSelect ((SOCKET) h, NULL, 0);
511 if (FD_ISSET (h, &handle_rfds))
513 if (FD_ISSET (h, &handle_wfds))
515 if (FD_ISSET (h, &handle_xfds))
522 if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
524 if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
526 if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
534 #else /* ! Native Windows. */
536 #include <sys/select.h>
537 #include <stddef.h> /* NULL */
544 rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
545 struct timeval *timeout)
549 /* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */
550 if (nfds < 0 || nfds > FD_SETSIZE)
555 for (i = 0; i < nfds; i++)
557 if (((rfds && FD_ISSET (i, rfds))
558 || (wfds && FD_ISSET (i, wfds))
559 || (xfds && FD_ISSET (i, xfds)))
564 /* Interix 3.5 has a bug: it does not support nfds == 0. */
572 return select (nfds, rfds, wfds, xfds, timeout);