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.li...@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 _______________________________________________ mc-devel mailing list https://mail.gnome.org/mailman/listinfo/mc-devel