From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Thu, 25 Oct 2012 16:45:06 +0200
Subject: [PATCH 5/5 v2] keyboard input: when an unknown sequence is seen, purge all buffered input
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@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
|
b
|
correct_key_code (int code) |
1216 | 1216 | /* --------------------------------------------------------------------------------------------- */ |
1217 | 1217 | |
1218 | 1218 | static int |
1219 | | xgetch_second (void) |
| 1219 | getch_with_timeout (unsigned delay_us) |
1220 | 1220 | { |
1221 | 1221 | fd_set Read_FD_Set; |
1222 | 1222 | int c; |
1223 | 1223 | struct timeval time_out; |
1224 | 1224 | |
1225 | | time_out.tv_sec = old_esc_mode_timeout / 1000000; |
1226 | | time_out.tv_usec = old_esc_mode_timeout % 1000000; |
| 1225 | time_out.tv_sec = delay_us / 1000000u; |
| 1226 | time_out.tv_usec = delay_us % 1000000u; |
1227 | 1227 | tty_nodelay (TRUE); |
1228 | 1228 | FD_ZERO (&Read_FD_Set); |
1229 | 1229 | FD_SET (input_fd, &Read_FD_Set); |
… |
… |
get_key_code (int no_delay) |
1891 | 1891 | seq_append = NULL; |
1892 | 1892 | } |
1893 | 1893 | if (bad_seq) |
| 1894 | { |
| 1895 | /* This is an unknown ESC sequence. |
| 1896 | * To prevent interpreting its tail as a random garbage, |
| 1897 | * eat and discard all buffered and quickly following chars. |
| 1898 | * Small, but non-zero timeout is needed to reconnect |
| 1899 | * escape sequence split up by e.g. a serial line. |
| 1900 | */ |
| 1901 | int paranoia = 20; |
| 1902 | while (getch_with_timeout (old_esc_mode_timeout) >= 0 && --paranoia != 0) |
| 1903 | continue; |
1894 | 1904 | goto nodelay_try_again; |
| 1905 | } |
1895 | 1906 | } |
1896 | 1907 | if ((d > 127 && d < 256) && use_8th_bit_as_meta) |
1897 | 1908 | { |
… |
… |
get_key_code (int no_delay) |
2009 | 2020 | goto nodelay_try_again; |
2010 | 2021 | } |
2011 | 2022 | esctime.tv_sec = -1; |
2012 | | c = xgetch_second (); |
2013 | | keylog (" c=xgetch_second()=%d\n", c); |
| 2023 | c = getch_with_timeout (old_esc_mode_timeout); |
| 2024 | keylog (" c=getch_with_timeout(%d)=%d\n", old_esc_mode_timeout, c); |
2014 | 2025 | if (c == -1) |
2015 | 2026 | { |
2016 | 2027 | pending_keys = seq_append = NULL; |