71
71
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
73
73
typedef DWORD (WINAPI *PNtQueryInformationFile)
74
(HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
74
(HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
80
80
#define IsConsoleHandle(h) (((long) (h) & 3) == 3)
83
IsSocketHandle(HANDLE h)
83
IsSocketHandle (HANDLE h)
85
85
WSANETWORKEVENTS ev;
121
121
case FILE_TYPE_PIPE:
124
NtQueryInformationFile = (PNtQueryInformationFile)
125
GetProcAddress (GetModuleHandle ("ntdll.dll"),
126
"NtQueryInformationFile");
124
NtQueryInformationFile = (PNtQueryInformationFile)
125
GetProcAddress (GetModuleHandle ("ntdll.dll"),
126
"NtQueryInformationFile");
130
130
if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
138
/* It was the write-end of the pipe. Check if it is writable.
139
If NtQueryInformationFile fails, optimistically assume the pipe is
140
writable. This could happen on Win9x, where NtQueryInformationFile
141
is not available, or if we inherit a pipe that doesn't permit
142
FILE_READ_ATTRIBUTES access on the write end (I think this should
143
not happen since WinXP SP2; WINE seems fine too). Otherwise,
144
ensure that enough space is available for atomic writes. */
138
/* It was the write-end of the pipe. Check if it is writable.
139
If NtQueryInformationFile fails, optimistically assume the pipe is
140
writable. This could happen on Win9x, where NtQueryInformationFile
141
is not available, or if we inherit a pipe that doesn't permit
142
FILE_READ_ATTRIBUTES access on the write end (I think this should
143
not happen since WinXP SP2; WINE seems fine too). Otherwise,
144
ensure that enough space is available for atomic writes. */
145
145
memset (&iosb, 0, sizeof (iosb));
146
146
memset (&fpli, 0, sizeof (fpli));
148
148
if (!NtQueryInformationFile
149
149
|| NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
150
FilePipeLocalInformation)
151
|| fpli.WriteQuotaAvailable >= PIPE_BUF
152
|| (fpli.OutboundQuota < PIPE_BUF &&
153
fpli.WriteQuotaAvailable == fpli.OutboundQuota))
150
FilePipeLocalInformation)
151
|| fpli.WriteQuotaAvailable >= PIPE_BUF
152
|| (fpli.OutboundQuota < PIPE_BUF &&
153
fpli.WriteQuotaAvailable == fpli.OutboundQuota))
158
158
case FILE_TYPE_CHAR:
160
160
if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
163
163
ret = WaitForSingleObject (h, 0);
164
164
if (ret == WAIT_OBJECT_0)
166
if (!IsConsoleHandle (h))
173
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
175
/* Screen buffers handles are filtered earlier. */
183
irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
184
bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
185
if (!bRet || avail == 0)
191
for (i = 0; i < avail; i++)
192
if (irbuffer[i].EventType == KEY_EVENT)
166
if (!IsConsoleHandle (h))
173
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
175
/* Screen buffers handles are filtered earlier. */
183
irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
184
bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
185
if (!bRet || avail == 0)
191
for (i = 0; i < avail; i++)
192
if (irbuffer[i].EventType == KEY_EVENT)
339
337
int requested = FD_CLOSE;
341
339
/* See above; socket handles are mapped onto select, but we
342
need to map descriptors to handles. */
340
need to map descriptors to handles. */
343
341
if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
345
343
requested |= FD_READ | FD_ACCEPT;
346
FD_SET ((SOCKET) h, rfds);
347
FD_SET ((SOCKET) h, &handle_rfds);
344
FD_SET ((SOCKET) h, rfds);
345
FD_SET ((SOCKET) h, &handle_rfds);
349
347
if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
351
349
requested |= FD_WRITE | FD_CONNECT;
352
FD_SET ((SOCKET) h, wfds);
353
FD_SET ((SOCKET) h, &handle_wfds);
350
FD_SET ((SOCKET) h, wfds);
351
FD_SET ((SOCKET) h, &handle_wfds);
355
353
if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
357
355
requested |= FD_OOB;
358
FD_SET ((SOCKET) h, xfds);
359
FD_SET ((SOCKET) h, &handle_xfds);
356
FD_SET ((SOCKET) h, xfds);
357
FD_SET ((SOCKET) h, &handle_xfds);
362
360
WSAEventSelect ((SOCKET) h, hEvent, requested);
367
365
handle_array[nhandles++] = h;
369
/* Poll now. If we get an event, do not wait below. */
367
/* Poll now. If we get an event, do not wait below. */
370
368
if (wait_timeout != 0
371
&& win32_poll_handle (h, i, &rbits, &wbits, &xbits))
369
&& win32_poll_handle (h, i, &rbits, &wbits, &xbits))
382
380
no need to call select again. */
383
381
rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
386
/* Restore the fd_sets for the other select we do below. */
384
/* Restore the fd_sets for the other select we do below. */
387
385
memcpy (&handle_rfds, rfds, sizeof (fd_set));
388
386
memcpy (&handle_wfds, wfds, sizeof (fd_set));
389
387
memcpy (&handle_xfds, xfds, sizeof (fd_set));
392
390
wait_timeout = 0;
397
395
ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
398
wait_timeout, QS_ALLINPUT);
396
wait_timeout, QS_ALLINPUT);
400
398
if (ret == WAIT_OBJECT_0 + nhandles)
402
400
/* new input of some other kind */
404
402
while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
406
404
TranslateMessage (&msg);
407
405
DispatchMessage (&msg);
414
412
/* If we haven't done it yet, check the status of the sockets. */
426
424
for (i = 0; i < nfds; i++)
428
426
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
431
429
h = (HANDLE) _get_osfhandle (i);
432
430
if (h != handle_array[nhandles])
434
/* Perform handle->descriptor mapping. Don't update rc, as these
435
results are counted in the return value of Winsock's select. */
432
/* Perform handle->descriptor mapping. Don't update rc, as these
433
results are counted in the return value of Winsock's select. */
436
434
WSAEventSelect ((SOCKET) h, NULL, 0);
437
435
if (FD_ISSET (h, &handle_rfds))
438
436
FD_SET (i, rfds);