Hi Paolo, > > For reference, here is the code that is in use in clisp to detect whether > > reading from a handle would hang or return immediately. The deal with > > ENABLE_LINE_INPUT is that PeekConsoleInput will say "yes there is something > > is available" as soon as the user has started typing a line, but ReadFile > > will hang until the user presses Return. > > Yes, it makes sense to add it to the select/poll emulations. I didn't > know about ENABLE_LINE_INPUT.
Well, this ENABLE_LINE_INPUT mode is the first obstacle when you try to implement the Lisp function READ-CHAR-NO-HANG from a console window, and it hangs between the moment you type the first character of the line and the final Return... I propose this code, based on the one from clisp (which I wrote and extensively tested years ago). Like you, I cannot test it for the moment. But anyway. Also, when GetNumberOfConsoleInputEvents fails, indicating that the handle refers to a character device other than a console (such as "NUL"), it's better to say that there is something to be read, so I changed except = TRUE; in this case to read = TRUE; 2008-10-04 Bruno Haible <[EMAIL PROTECTED]> * lib/winsock-select.c (win32_poll_handle): Improve code for character devices (both consoles and others). *** lib/winsock-select.c.orig 2008-10-04 18:57:04.000000000 +0200 --- lib/winsock-select.c 2008-10-04 18:55:30.000000000 +0200 *************** *** 82,88 **** { BOOL read, write, except; int i, ret; - INPUT_RECORD *irbuffer; DWORD avail, nbuffer; BOOL bRet; IO_STATUS_BLOCK iosb; --- 82,87 ---- *************** *** 142,158 **** { nbuffer = avail = 0; bRet = GetNumberOfConsoleInputEvents (h, &nbuffer); ! if (!bRet || nbuffer == 0) ! except = TRUE; ! ! irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD)); ! bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail); ! if (!bRet || avail == 0) ! except = TRUE; ! ! for (i = 0; i < avail; i++) ! if (irbuffer[i].EventType == KEY_EVENT) read = TRUE; } break; --- 141,197 ---- { nbuffer = avail = 0; bRet = GetNumberOfConsoleInputEvents (h, &nbuffer); ! if (bRet) ! { ! /* It's a console. */ ! if (nbuffer == 0) ! except = TRUE; ! else ! { ! INPUT_RECORD *irbuffer = ! (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD)); ! bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail); ! if (!bRet || avail == 0) ! except = TRUE; ! else ! { ! DWORD mode; ! bRet = GetConsoleMode (h, &mode); ! if (!bRet) ! except = TRUE; ! else if (mode & ENABLE_LINE_INPUT) ! { ! /* Look out for a Key-Down event corresponding to ! CR/LF. */ ! for (i = 0; i < avail; i++) ! if (irbuffer[i].EventType == KEY_EVENT ! && irbuffer[i].Event.KeyEvent.bKeyDown ! && irbuffer[i].Event.KeyEvent.uAsciiChar == CR) ! { ! read = TRUE; ! break; ! } ! } ! else ! { ! /* Look out for any Key-Down event. */ ! for (i = 0; i < avail; i++) ! if (irbuffer[i].EventType == KEY_EVENT ! && irbuffer[i].Event.KeyEvent.bKeyDown ! && irbuffer[i].Event.KeyEvent.uAsciiChar != 0) ! { ! read = TRUE; ! break; ! } ! } ! } ! } ! } ! else ! { ! /* Not a console. Possibly a device such as "NUL". */ read = TRUE; + } } break;