+ case CH_SOCKET:
+ {
+ struct timeval tv = {0, 0};
+
+ assert(INVALID_HANDLE_VALUE != handle);
+
+ fd_set s;
+ FD_ZERO(&s);
+ FD_SET((SOCKET)handle, &s);
+
+ int ret = select(0, &s, NULL, NULL, &tv);
+ if (SOCKET_ERROR == ret)
+ fprintf(stderr, "Can't select: %d\n", WSAGetLastError());
+
+ return ret != SOCKET_ERROR && ret != 0;
+ }
+
+ case CH_FILE:
+ return true;
+
+ case CH_CONSOLE:
+ {
+ PINPUT_RECORD pIRBuf;
+ DWORD NumPending;
+ DWORD NumPeeked;
+
+ /*
+ * Peek all pending console events
+ */
+ if (INVALID_HANDLE_VALUE == handle ||
+ !GetNumberOfConsoleInputEvents(handle, &NumPending) ||
+ NumPending == 0 ||
+ NULL == (pIRBuf = (PINPUT_RECORD)_alloca(NumPending * sizeof(INPUT_RECORD))))
+ return FALSE;
+
+ if (PeekConsoleInput(handle, pIRBuf, NumPending, &NumPeeked) &&
+ NumPeeked != 0L &&
+ NumPeeked <= NumPending)
+ {
+
+ /*
+ * Scan all of the peeked events to determine if any is a key event
+ * which should be recognized.
+ */
+ for ( ; NumPeeked > 0 ; NumPeeked--, pIRBuf++ )
+ {
+ if (KEY_EVENT == pIRBuf->EventType &&
+ pIRBuf->Event.KeyEvent.bKeyDown &&
+ pIRBuf->Event.KeyEvent.uChar.AsciiChar)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ case CH_SERIAL:
+ {
+ DWORD err;
+ COMSTAT comStat;
+
+ bool res = ClearCommError(handle, &err, &comStat);
+ assert(res);
+
+ return res ? comStat.cbInQue > 0 : false;
+ }
+
+ default:
+ assert(false);
+ return false;