bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] implement full-blown select(2) for winsock


From: Bruno Haible
Subject: Re: [PATCH v2] implement full-blown select(2) for winsock
Date: Sat, 4 Oct 2008 19:05:00 +0200
User-agent: KMail/1.5.4

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  <address@hidden>

        * 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;
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]