Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
The curious incident of the feep in the night-time
- X-seq: zsh-workers 48734
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: The curious incident of the feep in the night-time
- Date: Tue, 27 Apr 2021 14:35:14 -0700
- Archived-at: <https://zsh.org/workers/48734>
- List-id: <zsh-workers.zsh.org>
Starting from a fresh zsh -f:
% yy() { zle .send-break }
% zle -N yy
% 12345
(type ESC x yy RET, note that prompt silently returns)
%
On every subsequent invocation of yy, you'll get a beep ... until a
command at the prompt exits zero, and then just one following
invocation of yy will be silent again.
The problem is that lastval is never updated when execzlefunc()
returns nonzero from the nested call (first call is to yy, nested call
is to .send-break), so eventually execpline() returns the old lastval
to the outer execzlefunc(), which behaves as if yy succeeded and
therefore skips handlefeep().
The inner execzlefunc() is called from bin_zle_call() and the outer
one from zlecore(). I think it's correct that the inner one does not
handlefeep() [if it did, you'd feep twice] but something needs to set
lastval.
Further complicating this is that execcmd_exec() skips setting lastval
when ERRFLAG_INT is set, which is one of the bits used by sendbreak().
That's why the old value is still present when the outer execzlefunc()
returns.
4139 /*
4140 * In case of interruption assume builtin status
4141 * is less useful than what interrupt set.
4142 */
4143 if (!(errflag & ERRFLAG_INT))
4144 lastval = ret;
(indentation munged by copy-pasting tabs). The reference to "what
interrupt set" seems to imply that it is sendbreak() that should be
assigning lastval, because it is simulating a SIGINT and the handler
for SIGINT assigns lastval directly.
What eventually does set lastval = 1 is the parser noticing that the
lexer failed on the interrupt. Once that happens, further widget
calls don't reset it, so the feeps occur.
The other question is, to what should lastval be set? Is there
reliance on it being 1 here? (The parser only changes it [to 1] when
it is already 0.)
(For those confused about the Subject, see
https://en.wikipedia.org/wiki/The_Adventure_of_Silver_Blaze)
Messages sorted by:
Reverse Date,
Date,
Thread,
Author