Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: 'while do done' hangs interactive zsh



On Sun, May 16, 2021 at 9:15 AM Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
>
> On 5/16/21, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> > Specifically, the shell is interruptible by ^C.
>
> I just updated to latest git and I still can't ^C the "while do;
> done".

Curious.

> > The attached makes both "while do" and "do done" into parse errors;
>
> I use "do done" in production code so you can't remove that.

Let's try the attached, then?

I don't immediately see any reason that the SIGINT handler should not
always set errflag.

> > Because we're still in the parser, none of (list_pipe || chline ||
> > simple_pline) is true, so we never set breaks or errflag, only
> > lastval.  I'm not immediately sure what to do about that; perhaps just
> > move the errflag setting outside that test?

However, setting errflag is not sufficient to actually interrupt the
parse.  The attached just causes the empty loop condition to fail when
signaled.  Which I suppose could mean there's still a race condition
if the interrupt occurs during the empty loop body instead.
diff --git a/Src/exec.c b/Src/exec.c
index 6f09e0d9f..4575aa830 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1268,7 +1268,9 @@ execsimple(Estate state)
     } else {
 	int q = queue_signal_level();
 	dont_queue_signals();
-	if (code == WC_FUNCDEF)
+	if (errflag)
+	    lv = errflag;
+	else if (code == WC_FUNCDEF)
 	    lv = execfuncdef(state, NULL);
 	else
 	    lv = (execfuncs[code - WC_CURSH])(state, 0);
diff --git a/Src/signals.c b/Src/signals.c
index 4adf03202..2ce862490 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -672,9 +672,9 @@ zhandler(int sig)
 	    if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
 		isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL))
 		zexit(SIGINT, ZEXIT_SIGNAL);
+            errflag |= ERRFLAG_INT;
             if (list_pipe || chline || simple_pline) {
                 breaks = loops;
-                errflag |= ERRFLAG_INT;
 		inerrflush();
 		check_cursh_sig(SIGINT);
             }


Messages sorted by: Reverse Date, Date, Thread, Author