1
/* -*- buffer-read-only: t -*- vi: set ro: */
2
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3
/* Emulation for select(2)
4
Contributed by Paolo Bonzini.
6
Copyright 2008-2011 Free Software Foundation, Inc.
8
This file is part of gnulib.
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 3, or (at your option)
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along
21
with this program; if not, write to the Free Software Foundation,
22
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
28
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
31
#include <sys/types.h>
44
unsigned char in[FD_SETSIZE / CHAR_BIT];
45
unsigned char out[FD_SETSIZE / CHAR_BIT];
48
/* Declare data structures for ntdll functions. */
49
typedef struct _FILE_PIPE_LOCAL_INFORMATION {
51
ULONG NamedPipeConfiguration;
52
ULONG MaximumInstances;
53
ULONG CurrentInstances;
55
ULONG ReadDataAvailable;
57
ULONG WriteQuotaAvailable;
60
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
62
typedef struct _IO_STATUS_BLOCK
68
ULONG_PTR Information;
69
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
71
typedef enum _FILE_INFORMATION_CLASS {
72
FilePipeLocalInformation = 24
73
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
75
typedef DWORD (WINAPI *PNtQueryInformationFile)
76
(HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
82
#define IsConsoleHandle(h) (((long) (h) & 3) == 3)
85
IsSocketHandle (HANDLE h)
89
if (IsConsoleHandle (h))
92
/* Under Wine, it seems that getsockopt returns 0 for pipes too.
93
WSAEnumNetworkEvents instead distinguishes the two correctly. */
94
ev.lNetworkEvents = 0xDEADBEEF;
95
WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
96
return ev.lNetworkEvents != 0xDEADBEEF;
99
/* Compute output fd_sets for libc descriptor FD (whose Win32 handle is H). */
102
win32_poll_handle (HANDLE h, int fd, struct bitset *rbits, struct bitset *wbits,
103
struct bitset *xbits)
105
BOOL read, write, except;
107
INPUT_RECORD *irbuffer;
108
DWORD avail, nbuffer;
110
IO_STATUS_BLOCK iosb;
111
FILE_PIPE_LOCAL_INFORMATION fpli;
112
static PNtQueryInformationFile NtQueryInformationFile;
113
static BOOL once_only;
115
read = write = except = FALSE;
116
switch (GetFileType (h))
126
NtQueryInformationFile = (PNtQueryInformationFile)
127
GetProcAddress (GetModuleHandle ("ntdll.dll"),
128
"NtQueryInformationFile");
132
if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
137
else if (GetLastError () == ERROR_BROKEN_PIPE)
142
/* It was the write-end of the pipe. Check if it is writable.
143
If NtQueryInformationFile fails, optimistically assume the pipe is
144
writable. This could happen on Win9x, where NtQueryInformationFile
145
is not available, or if we inherit a pipe that doesn't permit
146
FILE_READ_ATTRIBUTES access on the write end (I think this should
147
not happen since WinXP SP2; WINE seems fine too). Otherwise,
148
ensure that enough space is available for atomic writes. */
149
memset (&iosb, 0, sizeof (iosb));
150
memset (&fpli, 0, sizeof (fpli));
152
if (!NtQueryInformationFile
153
|| NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
154
FilePipeLocalInformation)
155
|| fpli.WriteQuotaAvailable >= PIPE_BUF
156
|| (fpli.OutboundQuota < PIPE_BUF &&
157
fpli.WriteQuotaAvailable == fpli.OutboundQuota))
164
if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
167
ret = WaitForSingleObject (h, 0);
168
if (ret == WAIT_OBJECT_0)
170
if (!IsConsoleHandle (h))
177
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
179
/* Screen buffers handles are filtered earlier. */
187
irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
188
bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
189
if (!bRet || avail == 0)
195
for (i = 0; i < avail; i++)
196
if (irbuffer[i].EventType == KEY_EVENT)
202
ret = WaitForSingleObject (h, 0);
204
if (ret == WAIT_OBJECT_0)
211
if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
213
rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
217
if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
219
wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
223
if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
225
xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
233
rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
234
struct timeval *timeout)
236
static struct timeval tv0;
237
static HANDLE hEvent;
238
HANDLE h, handle_array[FD_SETSIZE + 2];
239
fd_set handle_rfds, handle_wfds, handle_xfds;
240
struct bitset rbits, wbits, xbits;
241
unsigned char anyfds_in[FD_SETSIZE / CHAR_BIT];
242
DWORD ret, wait_timeout, nhandles, nsock, nbuffer;
246
if (nfds > FD_SETSIZE)
250
wait_timeout = INFINITE;
253
wait_timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
255
/* select is also used as a portable usleep. */
256
if (!rfds && !wfds && !xfds)
258
Sleep (wait_timeout);
264
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
266
handle_array[0] = hEvent;
270
/* Copy descriptors to bitsets. At the same time, eliminate
271
bits in the "wrong" direction for console input buffers
272
and screen buffers, because screen buffers are waitable
273
and they will block until a character is available. */
274
memset (&rbits, 0, sizeof (rbits));
275
memset (&wbits, 0, sizeof (wbits));
276
memset (&xbits, 0, sizeof (xbits));
277
memset (anyfds_in, 0, sizeof (anyfds_in));
279
for (i = 0; i < rfds->fd_count; i++)
281
fd = rfds->fd_array[i];
282
h = (HANDLE) _get_osfhandle (fd);
283
if (IsConsoleHandle (h)
284
&& !GetNumberOfConsoleInputEvents (h, &nbuffer))
287
rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
288
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
291
rfds = (fd_set *) alloca (sizeof (fd_set));
294
for (i = 0; i < wfds->fd_count; i++)
296
fd = wfds->fd_array[i];
297
h = (HANDLE) _get_osfhandle (fd);
298
if (IsConsoleHandle (h)
299
&& GetNumberOfConsoleInputEvents (h, &nbuffer))
302
wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
303
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
306
wfds = (fd_set *) alloca (sizeof (fd_set));
309
for (i = 0; i < xfds->fd_count; i++)
311
fd = xfds->fd_array[i];
312
xbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
313
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
316
xfds = (fd_set *) alloca (sizeof (fd_set));
318
/* Zero all the fd_sets, including the application's. */
322
FD_ZERO (&handle_rfds);
323
FD_ZERO (&handle_wfds);
324
FD_ZERO (&handle_xfds);
326
/* Classify handles. Create fd sets for sockets, poll the others. */
327
for (i = 0; i < nfds; i++)
329
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
332
h = (HANDLE) _get_osfhandle (i);
339
if (IsSocketHandle (h))
341
int requested = FD_CLOSE;
343
/* See above; socket handles are mapped onto select, but we
344
need to map descriptors to handles. */
345
if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
347
requested |= FD_READ | FD_ACCEPT;
348
FD_SET ((SOCKET) h, rfds);
349
FD_SET ((SOCKET) h, &handle_rfds);
351
if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
353
requested |= FD_WRITE | FD_CONNECT;
354
FD_SET ((SOCKET) h, wfds);
355
FD_SET ((SOCKET) h, &handle_wfds);
357
if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
360
FD_SET ((SOCKET) h, xfds);
361
FD_SET ((SOCKET) h, &handle_xfds);
364
WSAEventSelect ((SOCKET) h, hEvent, requested);
369
handle_array[nhandles++] = h;
371
/* Poll now. If we get an event, do not wait below. */
372
if (wait_timeout != 0
373
&& win32_poll_handle (h, i, &rbits, &wbits, &xbits))
378
if (wait_timeout == 0 || nsock == 0)
382
/* See if we need to wait in the loop below. If any select is ready,
383
do MsgWaitForMultipleObjects anyway to dispatch messages, but
384
no need to call select again. */
385
rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
388
/* Restore the fd_sets for the other select we do below. */
389
memcpy (&handle_rfds, rfds, sizeof (fd_set));
390
memcpy (&handle_wfds, wfds, sizeof (fd_set));
391
memcpy (&handle_xfds, xfds, sizeof (fd_set));
399
ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
400
wait_timeout, QS_ALLINPUT);
402
if (ret == WAIT_OBJECT_0 + nhandles)
404
/* new input of some other kind */
406
while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
408
TranslateMessage (&msg);
409
DispatchMessage (&msg);
416
/* If we haven't done it yet, check the status of the sockets. */
417
if (rc == 0 && nsock > 0)
418
rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
420
/* Now fill in the results. */
425
/* Place a sentinel at the end of the array. */
426
handle_array[nhandles] = NULL;
428
for (i = 0; i < nfds; i++)
430
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
433
h = (HANDLE) _get_osfhandle (i);
434
if (h != handle_array[nhandles])
436
/* Perform handle->descriptor mapping. Don't update rc, as these
437
results are counted in the return value of Winsock's select. */
438
WSAEventSelect ((SOCKET) h, NULL, 0);
439
if (FD_ISSET (h, &handle_rfds))
441
if (FD_ISSET (h, &handle_wfds))
443
if (FD_ISSET (h, &handle_xfds))
450
win32_poll_handle (h, i, &rbits, &wbits, &xbits);
451
if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
456
if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
461
if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
472
#else /* ! Native Win32. */
474
#include <sys/select.h>
479
rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
480
struct timeval *timeout)
482
/* Interix 3.5 has a bug: it does not support nfds == 0. */
490
return select (nfds, rfds, wfds, xfds, timeout);