Cygwin: console: fix select() behaviour
- Previously, select() would return when only one key is typed even in canonical mode. With this patch, it returns after one line is completed.
This commit is contained in:
parent
bd627864ab
commit
8382778cdb
|
@ -1884,6 +1884,15 @@ public:
|
|||
tty_min tty_min_state;
|
||||
dev_console con;
|
||||
};
|
||||
bool input_ready;
|
||||
enum input_states
|
||||
{
|
||||
input_error = -1,
|
||||
input_processing = 0,
|
||||
input_ok = 1,
|
||||
input_signalled = 2,
|
||||
input_winch = 3
|
||||
};
|
||||
private:
|
||||
static const unsigned MAX_WRITE_CHARS;
|
||||
static console_state *shared_console_info;
|
||||
|
@ -1969,7 +1978,7 @@ private:
|
|||
void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);}
|
||||
void set_close_on_exec (bool val);
|
||||
void set_input_state ();
|
||||
void send_winch_maybe ();
|
||||
bool send_winch_maybe ();
|
||||
void setup ();
|
||||
bool set_unit ();
|
||||
static bool need_invisible ();
|
||||
|
@ -1992,6 +2001,7 @@ private:
|
|||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
input_states process_input_message ();
|
||||
friend tty_min * tty_list::get_cttyp ();
|
||||
};
|
||||
|
||||
|
|
|
@ -53,7 +53,9 @@ details. */
|
|||
|
||||
#define con (shared_console_info->con)
|
||||
#define srTop (con.b.srWindow.Top + con.scroll_region.Top)
|
||||
#define srBottom ((con.scroll_region.Bottom < 0) ? con.b.srWindow.Bottom : con.b.srWindow.Top + con.scroll_region.Bottom)
|
||||
#define srBottom ((con.scroll_region.Bottom < 0) ? \
|
||||
con.b.srWindow.Bottom : \
|
||||
con.b.srWindow.Top + con.scroll_region.Bottom)
|
||||
|
||||
const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
|
||||
|
||||
|
@ -149,16 +151,19 @@ fhandler_console::set_unit ()
|
|||
shared_unit : FH_ERROR;
|
||||
created = false;
|
||||
}
|
||||
else if ((!generic_console && (myself->ctty != -1 && !iscons_dev (myself->ctty)))
|
||||
else if ((!generic_console &&
|
||||
(myself->ctty != -1 && !iscons_dev (myself->ctty)))
|
||||
|| !(me = GetConsoleWindow ()))
|
||||
devset = FH_ERROR;
|
||||
else
|
||||
{
|
||||
created = true;
|
||||
shared_console_info = open_shared_console (me, cygheap->console_h, created);
|
||||
shared_console_info =
|
||||
open_shared_console (me, cygheap->console_h, created);
|
||||
ProtectHandleINH (cygheap->console_h);
|
||||
if (created)
|
||||
shared_console_info->tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me));
|
||||
shared_console_info->
|
||||
tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me));
|
||||
devset = (fh_devices) shared_console_info->tty_min_state.getntty ();
|
||||
if (created)
|
||||
con.owner = getpid ();
|
||||
|
@ -251,7 +256,8 @@ fhandler_console::set_raw_win32_keyboard_mode (bool new_mode)
|
|||
{
|
||||
bool old_mode = con.raw_win32_keyboard_mode;
|
||||
con.raw_win32_keyboard_mode = new_mode;
|
||||
syscall_printf ("raw keyboard mode %sabled", con.raw_win32_keyboard_mode ? "en" : "dis");
|
||||
syscall_printf ("raw keyboard mode %sabled",
|
||||
con.raw_win32_keyboard_mode ? "en" : "dis");
|
||||
return old_mode;
|
||||
};
|
||||
|
||||
|
@ -267,7 +273,7 @@ fhandler_console::set_cursor_maybe ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
fhandler_console::send_winch_maybe ()
|
||||
{
|
||||
SHORT y = con.dwWinSize.Y;
|
||||
|
@ -279,7 +285,9 @@ fhandler_console::send_winch_maybe ()
|
|||
con.scroll_region.Top = 0;
|
||||
con.scroll_region.Bottom = -1;
|
||||
get_ttyp ()->kill_pgrp (SIGWINCH);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check whether a mouse event is to be reported as an escape sequence */
|
||||
|
@ -299,7 +307,8 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
|
|||
con.dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left;
|
||||
con.dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top;
|
||||
|
||||
return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK)
|
||||
return ((mouse_event.dwEventFlags == 0
|
||||
|| mouse_event.dwEventFlags == DOUBLE_CLICK)
|
||||
&& mouse_event.dwButtonState != con.dwLastButtonState)
|
||||
|| mouse_event.dwEventFlags == MOUSE_WHEELED
|
||||
|| (mouse_event.dwEventFlags == MOUSE_MOVED
|
||||
|
@ -312,36 +321,17 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
|
|||
void __reg3
|
||||
fhandler_console::read (void *pv, size_t& buflen)
|
||||
{
|
||||
termios_printf ("read(%p,%d)", pv, buflen);
|
||||
|
||||
push_process_state process_state (PID_TTYIN);
|
||||
|
||||
HANDLE h = get_handle ();
|
||||
|
||||
#define buf ((char *) pv)
|
||||
|
||||
int ch;
|
||||
set_input_state ();
|
||||
|
||||
/* Check console read-ahead buffer filled from terminal requests */
|
||||
if (con.cons_rapoi && *con.cons_rapoi)
|
||||
{
|
||||
*buf = *con.cons_rapoi++;
|
||||
buflen = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int copied_chars = get_readahead_into_buffer (buf, buflen);
|
||||
|
||||
if (copied_chars)
|
||||
{
|
||||
buflen = copied_chars;
|
||||
return;
|
||||
}
|
||||
int copied_chars = 0;
|
||||
|
||||
DWORD timeout = is_nonblocking () ? 0 : INFINITE;
|
||||
char tmp[60];
|
||||
|
||||
termios ti = get_ttyp ()->ti;
|
||||
for (;;)
|
||||
set_input_state ();
|
||||
|
||||
while (!input_ready && !get_cons_readahead_valid ())
|
||||
{
|
||||
int bgres;
|
||||
if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
|
||||
|
@ -351,7 +341,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
}
|
||||
|
||||
set_cursor_maybe (); /* to make cursor appear on the screen immediately */
|
||||
switch (cygwait (h, timeout))
|
||||
switch (cygwait (get_handle (), timeout))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
|
@ -369,14 +359,74 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
goto err;
|
||||
}
|
||||
|
||||
#define buf ((char *) pv)
|
||||
|
||||
int ret;
|
||||
ret = process_input_message ();
|
||||
switch (ret)
|
||||
{
|
||||
case input_error:
|
||||
goto err;
|
||||
case input_processing:
|
||||
continue;
|
||||
case input_ok: /* input ready */
|
||||
break;
|
||||
case input_signalled: /* signalled */
|
||||
goto sig_exit;
|
||||
case input_winch:
|
||||
continue;
|
||||
default:
|
||||
/* Should not come here */
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check console read-ahead buffer filled from terminal requests */
|
||||
while (con.cons_rapoi && *con.cons_rapoi && buflen)
|
||||
{
|
||||
buf[copied_chars++] = *con.cons_rapoi++;
|
||||
buflen --;
|
||||
}
|
||||
|
||||
copied_chars +=
|
||||
get_readahead_into_buffer (buf + copied_chars, buflen);
|
||||
|
||||
if (!ralen)
|
||||
input_ready = false;
|
||||
|
||||
#undef buf
|
||||
|
||||
buflen = copied_chars;
|
||||
return;
|
||||
|
||||
err:
|
||||
__seterrno ();
|
||||
buflen = (size_t) -1;
|
||||
return;
|
||||
|
||||
sig_exit:
|
||||
set_sig_errno (EINTR);
|
||||
buflen = (size_t) -1;
|
||||
}
|
||||
|
||||
fhandler_console::input_states
|
||||
fhandler_console::process_input_message (void)
|
||||
{
|
||||
char tmp[60];
|
||||
|
||||
if (!shared_console_info)
|
||||
return input_error;
|
||||
|
||||
termios *ti = &(get_ttyp ()->ti);
|
||||
|
||||
DWORD nread;
|
||||
INPUT_RECORD input_rec;
|
||||
const char *toadd = NULL;
|
||||
|
||||
if (!ReadConsoleInputW (h, &input_rec, 1, &nread))
|
||||
if (!ReadConsoleInputW (get_handle (), &input_rec, 1, &nread))
|
||||
{
|
||||
syscall_printf ("ReadConsoleInput failed, %E");
|
||||
goto err; /* seems to be failure */
|
||||
termios_printf ("ReadConsoleInput failed, %E");
|
||||
return input_error;
|
||||
}
|
||||
|
||||
const WCHAR &unicode_char = input_rec.Event.KeyEvent.uChar.UnicodeChar;
|
||||
|
@ -397,7 +447,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
== (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED))
|
||||
{
|
||||
set_raw_win32_keyboard_mode (!con.raw_win32_keyboard_mode);
|
||||
continue;
|
||||
return input_processing;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -418,12 +468,12 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
/* Ignore key up events, except for Alt+Numpad events. */
|
||||
if (!input_rec.Event.KeyEvent.bKeyDown &&
|
||||
!is_alt_numpad_event (&input_rec))
|
||||
continue;
|
||||
return input_processing;
|
||||
/* Ignore Alt+Numpad keys. They are eventually handled below after
|
||||
releasing the Alt key. */
|
||||
if (input_rec.Event.KeyEvent.bKeyDown
|
||||
&& is_alt_numpad_key (&input_rec))
|
||||
continue;
|
||||
return input_processing;
|
||||
|
||||
if (ctrl_key_state & SHIFT_PRESSED)
|
||||
con.nModifiers |= 1;
|
||||
|
@ -464,7 +514,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
if (!toadd)
|
||||
{
|
||||
con.nModifiers = 0;
|
||||
continue;
|
||||
return input_processing;
|
||||
}
|
||||
nread = strlen (toadd);
|
||||
}
|
||||
|
@ -559,22 +609,26 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
{
|
||||
b = con.last_button_code;
|
||||
}
|
||||
else if (mouse_event.dwButtonState < con.dwLastButtonState && !con.ext_mouse_mode6)
|
||||
else if (mouse_event.dwButtonState < con.dwLastButtonState
|
||||
&& !con.ext_mouse_mode6)
|
||||
{
|
||||
b = 3;
|
||||
strcpy (sz, "btn up");
|
||||
}
|
||||
else if ((mouse_event.dwButtonState & 1) != (con.dwLastButtonState & 1))
|
||||
else if ((mouse_event.dwButtonState & 1)
|
||||
!= (con.dwLastButtonState & 1))
|
||||
{
|
||||
b = 0;
|
||||
strcpy (sz, "btn1 down");
|
||||
}
|
||||
else if ((mouse_event.dwButtonState & 2) != (con.dwLastButtonState & 2))
|
||||
else if ((mouse_event.dwButtonState & 2)
|
||||
!= (con.dwLastButtonState & 2))
|
||||
{
|
||||
b = 2;
|
||||
strcpy (sz, "btn2 down");
|
||||
}
|
||||
else if ((mouse_event.dwButtonState & 4) != (con.dwLastButtonState & 4))
|
||||
else if ((mouse_event.dwButtonState & 4)
|
||||
!= (con.dwLastButtonState & 4))
|
||||
{
|
||||
b = 1;
|
||||
strcpy (sz, "btn3 down");
|
||||
|
@ -693,43 +747,26 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
break;
|
||||
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
send_winch_maybe ();
|
||||
if (send_winch_maybe ())
|
||||
return input_winch;
|
||||
/* fall through */
|
||||
default:
|
||||
continue;
|
||||
return input_processing;
|
||||
}
|
||||
|
||||
if (toadd)
|
||||
{
|
||||
line_edit_status res = line_edit (toadd, nread, ti);
|
||||
ssize_t ret;
|
||||
line_edit_status res = line_edit (toadd, nread, *ti, &ret);
|
||||
if (res == line_edit_signalled)
|
||||
goto sig_exit;
|
||||
return input_signalled;
|
||||
else if (res == line_edit_input_done)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (buflen)
|
||||
if ((ch = get_readahead ()) < 0)
|
||||
break;
|
||||
else
|
||||
{
|
||||
buf[copied_chars++] = (unsigned char)(ch & 0xff);
|
||||
buflen--;
|
||||
input_ready = true;
|
||||
return input_ok;
|
||||
}
|
||||
#undef buf
|
||||
|
||||
buflen = copied_chars;
|
||||
return;
|
||||
|
||||
err:
|
||||
__seterrno ();
|
||||
buflen = (size_t) -1;
|
||||
return;
|
||||
|
||||
sig_exit:
|
||||
set_sig_errno (EINTR);
|
||||
buflen = (size_t) -1;
|
||||
}
|
||||
return input_processing;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -749,7 +786,8 @@ dev_console::fillin (HANDLE h)
|
|||
dwWinSize.Y = 1 + b.srWindow.Bottom - b.srWindow.Top;
|
||||
dwWinSize.X = 1 + b.srWindow.Right - b.srWindow.Left;
|
||||
if (b.dwCursorPosition.Y > dwEnd.Y
|
||||
|| (b.dwCursorPosition.Y >= dwEnd.Y && b.dwCursorPosition.X > dwEnd.X))
|
||||
|| (b.dwCursorPosition.Y >= dwEnd.Y
|
||||
&& b.dwCursorPosition.X > dwEnd.X))
|
||||
dwEnd = b.dwCursorPosition;
|
||||
}
|
||||
else
|
||||
|
@ -765,7 +803,8 @@ dev_console::fillin (HANDLE h)
|
|||
}
|
||||
|
||||
void __reg3
|
||||
dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, int yn)
|
||||
dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2,
|
||||
int xn, int yn)
|
||||
{
|
||||
/* Scroll the screen context.
|
||||
x1, y1 - ul corner
|
||||
|
@ -786,7 +825,8 @@ dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, in
|
|||
sr1.Bottom = y2 >= 0 ? y2 : b.srWindow.Bottom;
|
||||
sr2.Top = b.srWindow.Top + scroll_region.Top;
|
||||
sr2.Left = 0;
|
||||
sr2.Bottom = (scroll_region.Bottom < 0) ? b.srWindow.Bottom : b.srWindow.Top + scroll_region.Bottom;
|
||||
sr2.Bottom = (scroll_region.Bottom < 0) ?
|
||||
b.srWindow.Bottom : b.srWindow.Top + scroll_region.Bottom;
|
||||
sr2.Right = dwWinSize.X - 1;
|
||||
if (sr1.Bottom > sr2.Bottom && sr1.Top <= sr2.Bottom)
|
||||
sr1.Bottom = sr2.Bottom;
|
||||
|
@ -796,13 +836,15 @@ dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, in
|
|||
}
|
||||
|
||||
inline void
|
||||
fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2, int xn, int yn)
|
||||
fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2,
|
||||
int xn, int yn)
|
||||
{
|
||||
con.scroll_buffer (get_output_handle (), x1, y1, x2, y2, xn, yn);
|
||||
}
|
||||
|
||||
inline void
|
||||
fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2, int xn, int yn)
|
||||
fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2,
|
||||
int xn, int yn)
|
||||
{
|
||||
if (y1 >= 0)
|
||||
y1 += con.b.srWindow.Top;
|
||||
|
@ -1168,7 +1210,7 @@ fhandler_console::tcgetattr (struct termios *t)
|
|||
}
|
||||
|
||||
fhandler_console::fhandler_console (fh_devices unit) :
|
||||
fhandler_termios ()
|
||||
fhandler_termios (), input_ready (false)
|
||||
{
|
||||
if (unit > 0)
|
||||
dev ().parse (unit);
|
||||
|
@ -1869,16 +1911,19 @@ fhandler_console::char_command (char c)
|
|||
case 1: /* blinking block (default) */
|
||||
case 2: /* steady block */
|
||||
console_cursor_info.dwSize = 100;
|
||||
SetConsoleCursorInfo (get_output_handle (), &console_cursor_info);
|
||||
SetConsoleCursorInfo (get_output_handle (),
|
||||
&console_cursor_info);
|
||||
break;
|
||||
case 3: /* blinking underline */
|
||||
case 4: /* steady underline */
|
||||
console_cursor_info.dwSize = 10; /* or Windows default 25? */
|
||||
SetConsoleCursorInfo (get_output_handle (), &console_cursor_info);
|
||||
SetConsoleCursorInfo (get_output_handle (),
|
||||
&console_cursor_info);
|
||||
break;
|
||||
default: /* use value as percentage */
|
||||
console_cursor_info.dwSize = con.args[0];
|
||||
SetConsoleCursorInfo (get_output_handle (), &console_cursor_info);
|
||||
SetConsoleCursorInfo (get_output_handle (),
|
||||
&console_cursor_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1891,7 +1936,8 @@ fhandler_console::char_command (char c)
|
|||
{
|
||||
case 4: /* Insert mode */
|
||||
con.insert_mode = (c == 'h') ? true : false;
|
||||
syscall_printf ("insert mode %sabled", con.insert_mode ? "en" : "dis");
|
||||
syscall_printf ("insert mode %sabled",
|
||||
con.insert_mode ? "en" : "dis");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -2078,7 +2124,8 @@ fhandler_console::char_command (char c)
|
|||
/* Generate Secondary Device Attribute report, using 67 = ASCII 'C'
|
||||
to indicate Cygwin (convention used by Rxvt, Urxvt, Screen, Mintty),
|
||||
and cygwin version for terminal version. */
|
||||
__small_sprintf (buf, "\033[>67;%d%02d;0c", CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR);
|
||||
__small_sprintf (buf, "\033[>67;%d%02d;0c",
|
||||
CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR);
|
||||
else
|
||||
strcpy (buf, "\033[?6c");
|
||||
/* The generated report needs to be injected for read-ahead into the
|
||||
|
@ -2088,6 +2135,9 @@ fhandler_console::char_command (char c)
|
|||
con.cons_rapoi = NULL;
|
||||
strcpy (con.cons_rabuf, buf);
|
||||
con.cons_rapoi = con.cons_rabuf;
|
||||
/* Wake up read() or select() by sending a message
|
||||
which has no effect */
|
||||
PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0);
|
||||
break;
|
||||
case 'n':
|
||||
switch (con.args[0])
|
||||
|
@ -2100,6 +2150,9 @@ fhandler_console::char_command (char c)
|
|||
con.cons_rapoi = NULL;
|
||||
strcpy (con.cons_rabuf, buf);
|
||||
con.cons_rapoi = con.cons_rabuf;
|
||||
/* Wake up read() or select() by sending a message
|
||||
which has no effect */
|
||||
PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0);
|
||||
break;
|
||||
default:
|
||||
goto bad_escape;
|
||||
|
@ -2278,7 +2331,8 @@ fhandler_console::write_normal (const unsigned char *src,
|
|||
nfound - trunc_buf.buf);
|
||||
if (!write_console (write_buf, buf_len, done))
|
||||
{
|
||||
debug_printf ("multibyte sequence write failed, handle %p", get_output_handle ());
|
||||
debug_printf ("multibyte sequence write failed, handle %p",
|
||||
get_output_handle ());
|
||||
return 0;
|
||||
}
|
||||
found = src + (nfound - trunc_buf.buf - trunc_buf.len);
|
||||
|
@ -2378,7 +2432,8 @@ do_print:
|
|||
y--;
|
||||
}
|
||||
}
|
||||
cursor_set (false, ((get_ttyp ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1);
|
||||
cursor_set (false,
|
||||
((get_ttyp ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1);
|
||||
break;
|
||||
case BAK:
|
||||
cursor_rel (-1, 0);
|
||||
|
@ -2837,7 +2892,8 @@ fhandler_console::create_invisible_console_workaround ()
|
|||
|
||||
/* Create a new hidden process. Use the two event handles as
|
||||
argv[1] and argv[2]. */
|
||||
BOOL x = CreateProcessW (NULL, cmd, &sec_none_nih, &sec_none_nih, true,
|
||||
BOOL x = CreateProcessW (NULL, cmd,
|
||||
&sec_none_nih, &sec_none_nih, true,
|
||||
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
|
||||
if (x)
|
||||
{
|
||||
|
|
|
@ -202,7 +202,9 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
right value >= 0, matching the number of bits set in the
|
||||
fds records. if ret is 0, continue to loop. */
|
||||
ret = sel.poll (readfds, writefds, exceptfds);
|
||||
if (!ret)
|
||||
if (ret < 0)
|
||||
wait_state = select_stuff::select_signalled;
|
||||
else if (!ret)
|
||||
wait_state = select_stuff::select_set_zero;
|
||||
}
|
||||
/* Always clean up everything here. If we're looping then build it
|
||||
|
@ -479,6 +481,7 @@ was_timeout:
|
|||
events like mouse movements. The verify function will detect these
|
||||
situations. If it returns false, then this wakeup was a false alarm
|
||||
and we should go back to waiting. */
|
||||
int ret = 0;
|
||||
while ((s = s->next))
|
||||
if (s->saw_error ())
|
||||
{
|
||||
|
@ -488,8 +491,13 @@ was_timeout:
|
|||
}
|
||||
else if ((((wait_ret >= m && s->windows_handle)
|
||||
|| s->h == w4[wait_ret]))
|
||||
&& s->verify (s, readfds, writefds, exceptfds))
|
||||
&& (ret = s->verify (s, readfds, writefds, exceptfds)) > 0)
|
||||
res = select_ok;
|
||||
else if (ret < 0)
|
||||
{
|
||||
res = select_signalled;
|
||||
goto out;
|
||||
}
|
||||
|
||||
select_printf ("res after verify %d", res);
|
||||
break;
|
||||
|
@ -539,8 +547,12 @@ select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
|
|||
int n = 0;
|
||||
select_record *s = &start;
|
||||
while ((s = s->next))
|
||||
n += (!s->peek || s->peek (s, true)) ?
|
||||
set_bits (s, readfds, writefds, exceptfds) : 0;
|
||||
{
|
||||
int ret = s->peek ? s->peek (s, true) : 1;
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
n += (ret > 0) ? set_bits (s, readfds, writefds, exceptfds) : 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -1010,16 +1022,10 @@ peek_console (select_record *me, bool)
|
|||
return me->write_ready;
|
||||
|
||||
if (fh->get_cons_readahead_valid ())
|
||||
{
|
||||
select_printf ("cons_readahead");
|
||||
return me->read_ready = true;
|
||||
}
|
||||
|
||||
if (fh->get_readahead_valid ())
|
||||
{
|
||||
select_printf ("readahead");
|
||||
if (fh->input_ready)
|
||||
return me->read_ready = true;
|
||||
}
|
||||
|
||||
if (me->read_ready)
|
||||
{
|
||||
|
@ -1030,54 +1036,20 @@ peek_console (select_record *me, bool)
|
|||
INPUT_RECORD irec;
|
||||
DWORD events_read;
|
||||
HANDLE h;
|
||||
char tmpbuf[17];
|
||||
set_handle_or_return_if_not_open (h, me);
|
||||
|
||||
for (;;)
|
||||
while (!fh->input_ready && !fh->get_cons_readahead_valid ())
|
||||
if (fh->bg_check (SIGTTIN, true) <= bg_eof)
|
||||
return me->read_ready = true;
|
||||
else if (!PeekConsoleInputW (h, &irec, 1, &events_read) || !events_read)
|
||||
break;
|
||||
else
|
||||
else if (fhandler_console::input_winch == fh->process_input_message ())
|
||||
{
|
||||
fh->send_winch_maybe ();
|
||||
if (irec.EventType == KEY_EVENT)
|
||||
{
|
||||
if (irec.Event.KeyEvent.bKeyDown)
|
||||
{
|
||||
/* Ignore Alt+Numpad keys. They are eventually handled in the
|
||||
key-up case below. */
|
||||
if (is_alt_numpad_key (&irec))
|
||||
;
|
||||
/* Handle normal input. */
|
||||
else if (irec.Event.KeyEvent.uChar.UnicodeChar
|
||||
|| fhandler_console::get_nonascii_key (irec, tmpbuf))
|
||||
return me->read_ready = true;
|
||||
/* Allow Ctrl-Space for ^@ */
|
||||
else if ( (irec.Event.KeyEvent.wVirtualKeyCode == VK_SPACE
|
||||
|| irec.Event.KeyEvent.wVirtualKeyCode == '2')
|
||||
&& (irec.Event.KeyEvent.dwControlKeyState &
|
||||
(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
&& !(irec.Event.KeyEvent.dwControlKeyState
|
||||
& (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) )
|
||||
return me->read_ready = true;
|
||||
set_sig_errno (EINTR);
|
||||
return -1;
|
||||
}
|
||||
/* Ignore key up events, except for Alt+Numpad events. */
|
||||
else if (is_alt_numpad_event (&irec))
|
||||
if (fh->input_ready || fh->get_cons_readahead_valid ())
|
||||
return me->read_ready = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (irec.EventType == MOUSE_EVENT
|
||||
&& fh->mouse_aware (irec.Event.MouseEvent))
|
||||
return me->read_ready = true;
|
||||
if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
|
||||
return me->read_ready = true;
|
||||
}
|
||||
|
||||
/* Read and discard the event */
|
||||
ReadConsoleInputW (h, &irec, 1, &events_read);
|
||||
}
|
||||
|
||||
return me->write_ready;
|
||||
}
|
||||
|
@ -1089,7 +1061,6 @@ verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
|
|||
return peek_console (me, true);
|
||||
}
|
||||
|
||||
|
||||
select_record *
|
||||
fhandler_console::select_read (select_stuff *ss)
|
||||
{
|
||||
|
@ -1104,7 +1075,7 @@ fhandler_console::select_read (select_stuff *ss)
|
|||
s->peek = peek_console;
|
||||
s->h = get_handle ();
|
||||
s->read_selected = true;
|
||||
s->read_ready = get_readahead_valid ();
|
||||
s->read_ready = input_ready || get_cons_readahead_valid ();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue