public inbox for cygwin-developers@cygwin.com
 help / color / mirror / Atom feed
* read vs select on mouse events in console
@ 2022-12-22 14:55 Thomas Wolff
  2022-12-23  3:24 ` Takashi Yano
  0 siblings, 1 reply; 6+ messages in thread
From: Thomas Wolff @ 2022-12-22 14:55 UTC (permalink / raw)
  To: cygwin-developers

[-- Attachment #1: Type: text/plain, Size: 994 bytes --]

When I added mouse notification support to the console long ago, I 
deliberately introduced a function mouse_aware() which was common 
between the console version of function read() and the console branch of 
function select(), in order to make sure by design that inconsistencies 
between them could never occur.
Now I noticed that by some change, mouse_aware() is not used anymore in 
select() code.
This means that it could happen that either a mouse event would be 
indicated by select() but then not be delivered by read(), so read() 
could stall,
or (possibly, not sure) the other way round, a mouse event available for 
delivery would not be recognized by select().
The attached test case is a rough demonstration of the issue. It uses 
mouse mode DECSET 1000 which has a limited range of mouse coordinates.
Run it in a maximized console, click into the upper left area, then 
further apart toward lower right, and eventually the program will stall 
until another key is pressed.
Thomas

[-- Attachment #2: test-select.c --]
[-- Type: text/plain, Size: 1874 bytes --]

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#include <sys/select.h>
#include <time.h>
#include <signal.h>

struct termios saved_tattr;

void
restore_tattr (void)
{
  if (isatty (STDIN_FILENO))
    tcsetattr (STDIN_FILENO, TCSANOW, &saved_tattr);
}

int
ready_select ()
{
  struct timeval timeoutstru;
  fd_set readfds;
  int nfds;
  static int rv = 0;

  timeoutstru.tv_sec = 0;
  timeoutstru.tv_usec = 800000;

  FD_ZERO (& readfds);
  FD_SET (STDIN_FILENO, & readfds);
  nfds = select (STDIN_FILENO + 1, & readfds, 0, 0, & timeoutstru);
  printf ("(%d)", nfds);
  fflush (stdout);
  return nfds;
}

int
main (void)
{
  if (isatty (STDIN_FILENO)) {
    struct termios tattr;
    tcgetattr (STDIN_FILENO, &saved_tattr);
    tattr = saved_tattr;
/*
*/
    tattr.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    tattr.c_oflag &= ~OPOST;
    tattr.c_cflag &= ~(CSIZE|PARENB);
    tattr.c_cflag |= CS8;
    tattr.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
    /* use miminal change for test case: */
    tattr.c_lflag &= ~(ICANON);
    tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
    atexit (restore_tattr);
  }
  setbuf (stdout, 0);

//  printf ("\033[?1000h\033[?1006h\033[?1004h");
  printf ("\033[?1000h\033[?1004h");
  while (1) {
    unsigned char c;
    int res;

    while (! ready_select ()) {
    }

    res = read (STDIN_FILENO, & c, 1);
    if (c == '\x04') {
      break;
    }
    switch (c & 0xFF) {
      case 0x00 ... 0x1f:  putchar ('^'); putchar (c + 0x40);
                           if (c == '\r') printf ("\r\n");
                           break;
      case 0x7f: putchar ('^'); putchar ('?'); break;
      case 0x80 ... 0xFF: printf ("\\x%2X", c); break;
      default: putchar (c);
    }
    fflush (stdout);
  }
  printf ("\033[?1000l\033[?1004l\r\nbye\r\n");
  return 0;
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-12-24 11:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-22 14:55 read vs select on mouse events in console Thomas Wolff
2022-12-23  3:24 ` Takashi Yano
2022-12-23  9:08   ` Thomas Wolff
2022-12-23 10:19     ` Takashi Yano
2022-12-23 12:03       ` Thomas Wolff
2022-12-24 11:37         ` Takashi Yano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).