• Tom Lane's avatar
    Cope with Readline's failure to track SIGWINCH events outside of input. · 2ec477dc
    Tom Lane authored
    It emerges that libreadline doesn't notice terminal window size change
    events unless they occur while collecting input.  This is easy to stumble
    over if you resize the window while using a pager to look at query output,
    but it can be demonstrated without any pager involvement.  The symptom is
    that queries exceeding one line are misdisplayed during subsequent input
    cycles, because libreadline has the wrong idea of the screen dimensions.
    
    The safest, simplest way to fix this is to call rl_reset_screen_size()
    just before calling readline().  That causes an extra ioctl(TIOCGWINSZ)
    for every command; but since it only happens when reading from a tty, the
    performance impact should be negligible.  A more valid objection is that
    this still leaves a tiny window during entry to readline() wherein delivery
    of SIGWINCH will be missed; but the practical consequences of that are
    probably negligible.  In any case, there doesn't seem to be any good way to
    avoid the race, since readline exposes no functions that seem safe to call
    from a generic signal handler --- rl_reset_screen_size() certainly isn't.
    
    It turns out that we also need an explicit rl_initialize() call, else
    rl_reset_screen_size() dumps core when called before the first readline()
    call.
    
    rl_reset_screen_size() is not present in old versions of libreadline,
    so we need a configure test for that.  (rl_initialize() is present at
    least back to readline 4.0, so we won't bother with a test for it.)
    We would need a configure test anyway since libedit's emulation of
    libreadline doesn't currently include such a function.  Fortunately,
    libedit seems not to have any corresponding bug.
    
    Merlin Moncure, adjusted a bit by me
    2ec477dc
configure 456 KB