bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bash Missing Terminal Resize Events


From: Bruce Evans
Subject: Re: Bash Missing Terminal Resize Events
Date: Mon, 20 Nov 2017 12:05:49 -0000 (UTC)

In article <address@hidden>,
Evan Klitzke  <address@hidden> wrote:
> 
> Bash will miss terminal resize events in the following scenario:
> 
> * Open a terminal (I tested with xterm and gnome-terminal)
> * Run vim
> * Resize the terminal
> * Background vim using Ctrl-Z
> 
> At the point SIGWINCH will have been delivered to vim, but not to bash.

I saw this sort of problem on an old system (with bash-1.4.7) and wondered
if anyone has fixed it.

Job control seemed to be working perfectly to POSIX spec, but POSIX spec
just doesn't work for SIGWINCH, and it is not clear how it can work even
for SIGHUP.  IIRC, terminals are specified to only send SIGWINCH to the
foreground process.  That is vim in this case.  Nothing relays the signal
to the next foreground process (usually the shell).  For SIGHUP, there is
a lot of relaying down the process tree, but nothing up or sideways IIRC,
so I don't see how SIGHUP can work right unless it is delivered to the
shell at the top of the tree.  However, when when SIGHUP is generated by
terminal disconnection, the disconnection also causes read() to return
EOF and most POSIX processes exit when read() on stdin returns EOF.

> Bash is in the read part of the read-eval loop, but it still thinks the
> terminal has the original dimensions. This causes readline to wrap input
> incorrectly. You can also see this by GDB attaching to the bash process and

I don't see any way to handle it except to poll.  Not just in the shell,
and not just in the read loop, and not just when the syscall returns EINTR.

It is also necessary to turn off SA_RESTART for almost all caught signals
before every system call like an interactive read(), so that read() returns
after all signals of interest.  This gets complicated with libraries and
technically undefined behaviour from using longjmp().

> examining the value of _rl_screenwidth, which will be the old screen width.
> If you manually SIGWINCH bash, then readline will re-query the terminal
> dimensions and input will wrap correctly. Note that this problem isn't
> specific to vim.

vim could relay the signal to the shell, but that is unreasonable for most
programs.  Especially ones like cat that are supposed to be device-dependent.

X > I think that bash should re-query the terminal size every time it returns
X > from handling a job. As I understand, the overhead is making a single
X > TIOCGSIZE ioctl, which is minuscule, especially considering it only has to
X > be done once per line of input.

Something like that

I'm more interested in the kernel side of this, for pure terminals without
a window manager.  A better designed job control system might have stickier
signals for state changes like SIGWINCH and SIGHUP.  Someday I will try
modifying a terminal driver to send SIGWINCH to the foreground process when
the size has changed but this process hasn't already been signaled.  Since
SIGWINCH is ignored by default, this shouldn't break anything.

Bruce


reply via email to

[Prev in Thread] Current Thread [Next in Thread]