Skip to content
Snippets Groups Projects
Commit 2bfba9e4 authored by Niklas Hambüchen's avatar Niklas Hambüchen Committed by Ben Gamari
Browse files

base: Fix mixed tabs/spaces indentation in inputReady.c

Reviewers: bgamari, austin, hvr

Reviewed By: bgamari

Subscribers: rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D3952
parent f4d50a0e
No related branches found
No related tags found
No related merge requests found
......@@ -98,40 +98,65 @@ fdReady(int fd, int write, int msecs, int isSock)
/* 1 => Input ready, 0 => not ready, -1 => error */
return (ready);
}
else {
} else {
DWORD rc;
HANDLE hFile = (HANDLE)_get_osfhandle(fd);
DWORD avail;
switch (GetFileType(hFile)) {
case FILE_TYPE_CHAR:
{
INPUT_RECORD buf[1];
DWORD count;
case FILE_TYPE_CHAR:
{
INPUT_RECORD buf[1];
DWORD count;
// nightmare. A Console Handle will appear to be ready
// (WaitForSingleObject() returned WAIT_OBJECT_0) when
// it has events in its input buffer, but these events might
// not be keyboard events, so when we read from the Handle the
// read() will block. So here we try to discard non-keyboard
// events from a console handle's input buffer and then try
// the WaitForSingleObject() again.
// nightmare. A Console Handle will appear to be ready
// (WaitForSingleObject() returned WAIT_OBJECT_0) when
// it has events in its input buffer, but these events might
// not be keyboard events, so when we read from the Handle the
// read() will block. So here we try to discard non-keyboard
// events from a console handle's input buffer and then try
// the WaitForSingleObject() again.
while (1) // keep trying until we find a real key event
while (1) // keep trying until we find a real key event
{
rc = WaitForSingleObject( hFile, msecs );
switch (rc) {
case WAIT_TIMEOUT: return 0;
case WAIT_OBJECT_0: break;
default: /* WAIT_FAILED */ maperrno(); return -1;
case WAIT_TIMEOUT: return 0;
case WAIT_OBJECT_0: break;
default: /* WAIT_FAILED */ maperrno(); return -1;
}
while (1) // discard non-key events
{
rc = PeekConsoleInput(hFile, buf, 1, &count);
// printf("peek, rc=%d, count=%d, type=%d\n", rc, count, buf[0].EventType);
if (rc == 0) {
rc = GetLastError();
if (rc == ERROR_INVALID_HANDLE || rc == ERROR_INVALID_FUNCTION) {
return 1;
} else {
maperrno();
return -1;
}
}
if (count == 0) break; // no more events => wait again
// discard console events that are not "key down", because
// these will also be discarded by ReadFile().
if (buf[0].EventType == KEY_EVENT &&
buf[0].Event.KeyEvent.bKeyDown &&
buf[0].Event.KeyEvent.uChar.AsciiChar != '\0')
{
// it's a proper keypress:
return 1;
}
else
{
rc = PeekConsoleInput(hFile, buf, 1, &count);
// printf("peek, rc=%d, count=%d, type=%d\n", rc, count, buf[0].EventType);
// it's a non-key event, a key up event, or a
// non-character key (e.g. shift). discard it.
rc = ReadConsoleInput(hFile, buf, 1, &count);
if (rc == 0) {
rc = GetLastError();
if (rc == ERROR_INVALID_HANDLE || rc == ERROR_INVALID_FUNCTION) {
......@@ -141,75 +166,49 @@ fdReady(int fd, int write, int msecs, int isSock)
return -1;
}
}
if (count == 0) break; // no more events => wait again
// discard console events that are not "key down", because
// these will also be discarded by ReadFile().
if (buf[0].EventType == KEY_EVENT &&
buf[0].Event.KeyEvent.bKeyDown &&
buf[0].Event.KeyEvent.uChar.AsciiChar != '\0')
{
// it's a proper keypress:
return 1;
}
else
{
// it's a non-key event, a key up event, or a
// non-character key (e.g. shift). discard it.
rc = ReadConsoleInput(hFile, buf, 1, &count);
if (rc == 0) {
rc = GetLastError();
if (rc == ERROR_INVALID_HANDLE || rc == ERROR_INVALID_FUNCTION) {
return 1;
} else {
maperrno();
return -1;
}
}
}
}
}
}
}
}
case FILE_TYPE_DISK:
// assume that disk files are always ready:
return 1;
case FILE_TYPE_PIPE:
// WaitForMultipleObjects() doesn't work for pipes (it
// always returns WAIT_OBJECT_0 even when no data is
// available). If the HANDLE is a pipe, therefore, we try
// PeekNamedPipe:
//
rc = PeekNamedPipe( hFile, NULL, 0, NULL, &avail, NULL );
if (rc != 0) {
if (avail != 0) {
return 1;
case FILE_TYPE_DISK:
// assume that disk files are always ready:
return 1;
case FILE_TYPE_PIPE:
// WaitForMultipleObjects() doesn't work for pipes (it
// always returns WAIT_OBJECT_0 even when no data is
// available). If the HANDLE is a pipe, therefore, we try
// PeekNamedPipe:
//
rc = PeekNamedPipe( hFile, NULL, 0, NULL, &avail, NULL );
if (rc != 0) {
if (avail != 0) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
} else {
rc = GetLastError();
if (rc == ERROR_BROKEN_PIPE) {
return 1; // this is probably what we want
}
if (rc != ERROR_INVALID_HANDLE && rc != ERROR_INVALID_FUNCTION) {
maperrno();
return -1;
rc = GetLastError();
if (rc == ERROR_BROKEN_PIPE) {
return 1; // this is probably what we want
}
if (rc != ERROR_INVALID_HANDLE && rc != ERROR_INVALID_FUNCTION) {
maperrno();
return -1;
}
}
}
/* PeekNamedPipe didn't work - fall through to the general case */
/* PeekNamedPipe didn't work - fall through to the general case */
default:
rc = WaitForSingleObject( hFile, msecs );
default:
rc = WaitForSingleObject( hFile, msecs );
/* 1 => Input ready, 0 => not ready, -1 => error */
switch (rc) {
case WAIT_TIMEOUT: return 0;
case WAIT_OBJECT_0: return 1;
default: /* WAIT_FAILED */ maperrno(); return -1;
}
/* 1 => Input ready, 0 => not ready, -1 => error */
switch (rc) {
case WAIT_TIMEOUT: return 0;
case WAIT_OBJECT_0: return 1;
default: /* WAIT_FAILED */ maperrno(); return -1;
}
}
}
#endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment