Ticket #2988: when an unknown sequence is seen, purge all buffered input.patch

File when an unknown sequence is seen, purge all buffered input.patch, 2.9 KB (added by slavazanko, 12 years ago)
  • lib/tty/key.c

    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) 
    12161216/* --------------------------------------------------------------------------------------------- */ 
    12171217 
    12181218static int 
    1219 xgetch_second (void) 
     1219getch_with_timeout (unsigned delay_us) 
    12201220{ 
    12211221    fd_set Read_FD_Set; 
    12221222    int c; 
    12231223    struct timeval time_out; 
    12241224 
    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; 
    12271227    tty_nodelay (TRUE); 
    12281228    FD_ZERO (&Read_FD_Set); 
    12291229    FD_SET (input_fd, &Read_FD_Set); 
    get_key_code (int no_delay) 
    18911891                    seq_append = NULL; 
    18921892                } 
    18931893                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; 
    18941904                    goto nodelay_try_again; 
     1905                } 
    18951906            } 
    18961907            if ((d > 127 && d < 256) && use_8th_bit_as_meta) 
    18971908            { 
    get_key_code (int no_delay) 
    20092020                    goto nodelay_try_again; 
    20102021                } 
    20112022                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); 
    20142025                if (c == -1) 
    20152026                { 
    20162027                    pending_keys = seq_append = NULL;