[PATCH 5/5 v2] keyboard input: when an unknown sequence is seen, purge all buffered input
Denys Vlasenko
vda.linux at googlemail.com
Thu Oct 25 14:45:06 UTC 2012
When we see an unknown sequence, it is not enough
to drop already received part - there can be more of it
coming over e.g. a serial line.
To prevent interpreting it as a random garbage,
eat and discard all chars that follow.
Small, but non-zero timeout is needed to reconnect
escape sequence split up by a serial line.
Before this change, Ctrl-Alt-Shift-Right_Arrow generates "1;8C"
bogus "input" in MC on my machine; after the change,
nothing is generated.
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
lib/tty/key.c | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/tty/key.c b/lib/tty/key.c
index 9b97aa8..818b2e6 100644
--- a/lib/tty/key.c
+++ b/lib/tty/key.c
@@ -1216,14 +1216,14 @@ correct_key_code (int code)
/* --------------------------------------------------------------------------------------------- */
static int
-xgetch_second (void)
+getch_with_timeout (unsigned delay_us)
{
fd_set Read_FD_Set;
int c;
struct timeval time_out;
- time_out.tv_sec = old_esc_mode_timeout / 1000000;
- time_out.tv_usec = old_esc_mode_timeout % 1000000;
+ time_out.tv_sec = delay_us / 1000000u;
+ time_out.tv_usec = delay_us % 1000000u;
tty_nodelay (TRUE);
FD_ZERO (&Read_FD_Set);
FD_SET (input_fd, &Read_FD_Set);
@@ -1891,7 +1891,18 @@ get_key_code (int no_delay)
seq_append = NULL;
}
if (bad_seq)
+ {
+ /* This is an unknown ESC sequence.
+ * To prevent interpreting its tail as a random garbage,
+ * eat and discard all buffered and quickly following chars.
+ * Small, but non-zero timeout is needed to reconnect
+ * escape sequence split up by e.g. a serial line.
+ */
+ int paranoia = 20;
+ while (getch_with_timeout (old_esc_mode_timeout) >= 0 && --paranoia != 0)
+ continue;
goto nodelay_try_again;
+ }
}
if ((d > 127 && d < 256) && use_8th_bit_as_meta)
{
@@ -2009,8 +2020,8 @@ get_key_code (int no_delay)
goto nodelay_try_again;
}
esctime.tv_sec = -1;
- c = xgetch_second ();
- keylog (" c=xgetch_second()=%d\n", c);
+ c = getch_with_timeout (old_esc_mode_timeout);
+ keylog (" c=getch_with_timeout(%d)=%d\n", old_esc_mode_timeout, c);
if (c == -1)
{
pending_keys = seq_append = NULL;
--
1.7.7.6
More information about the mc-devel
mailing list