zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: The curious incident of the feep in the night-time
Date: Tue, 27 Apr 2021 14:35:14 -0700	[thread overview]
Message-ID: <CAH+w=7aadRw01MvNZjvgF=eNGJBO-+pUKmcA8meS83M96ysNfA@mail.gmail.com> (raw)

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)


             reply	other threads:[~2021-04-27 21:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-27 21:35 Bart Schaefer [this message]
2021-04-28  7:26 ` Stephane Chazelas
2021-04-28 18:15   ` Bart Schaefer
2021-04-29  1:04 ` Bart Schaefer
2021-04-29 18:27   ` Bart Schaefer
2021-05-02 22:20     ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7aadRw01MvNZjvgF=eNGJBO-+pUKmcA8meS83M96ysNfA@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).