zsh-workers
 help / color / mirror / Atom feed
* 'while do done' hangs interactive zsh
@ 2021-05-16  9:16 Arseny Maslennikov
  2021-05-16 14:28 ` Bart Schaefer
  2021-05-16 16:43 ` 'while do done' hangs interactive zsh Stephane Chazelas
  0 siblings, 2 replies; 14+ messages in thread
From: Arseny Maslennikov @ 2021-05-16  9:16 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

Hi everyone!

When zsh tries to execute "while do; done", it enters a busy loop:

% dash -c 'while do; done'
dash: 1: Syntax error: "do" unexpected
% bash -c 'while do; done'
bash: -c: line 1: syntax error near unexpected token `do'
bash: -c: line 1: `while do; done'
% zsh -c 'while do; done' 	# never finishes/prompts by itself
^C
zsh -c 'while do; done'  27,73s user 0,00s system 99% cpu 27,732 total 4k maxrss

Even more, if the user enters "while do; done" in an interactive zsh
instance, the busy loop is not interruptible by ^C, ^\ or ^Z; the shell
has to be killed via some external means.

To be fair, I have discovered the bug with the semicolon omitted ("while do done").

Could we do something about this?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16  9:16 'while do done' hangs interactive zsh Arseny Maslennikov
@ 2021-05-16 14:28 ` Bart Schaefer
  2021-05-16 15:46   ` Bart Schaefer
  2021-05-16 16:43 ` 'while do done' hangs interactive zsh Stephane Chazelas
  1 sibling, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 14:28 UTC (permalink / raw)
  To: Arseny Maslennikov; +Cc: Zsh hackers list

On Sun, May 16, 2021 at 2:17 AM Arseny Maslennikov <ar@cs.msu.ru> wrote:
>
> When zsh tries to execute "while do; done", it enters a busy loop:

I can reproduce this, and it is not dependent on the shortloops option.

> Even more, if the user enters "while do; done" in an interactive zsh
> instance, the busy loop is not interruptible by ^C, ^\ or ^Z; the shell
> has to be killed via some external means.

I can NOT reproduce this in the latest revision from git, but I can
reproduce it in zsh-5.8.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 14:28 ` Bart Schaefer
@ 2021-05-16 15:46   ` Bart Schaefer
  2021-05-16 16:15     ` Mikael Magnusson
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 15:46 UTC (permalink / raw)
  To: Arseny Maslennikov; +Cc: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 1551 bytes --]

On Sun, May 16, 2021 at 7:28 AM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> > Even more, if the user enters "while do; done" in an interactive zsh
> > instance, the busy loop is not interruptible by ^C, ^\ or ^Z; the shell
> > has to be killed via some external means.
>
> I can NOT reproduce this in the latest revision from git, but I can
> reproduce it in zsh-5.8.

Specifically, the shell is interruptible by ^C.  I haven't attempted
to bisect where this was introduced; there are no obvious deltas to
signals.c, loop.c, or parse.c to explain it.

It is impossible to interrupt the parser with SIGINT.  zhandler is
entered with signal queueing enabled; when signals are allowed again,
zhandler is called again and we pass through this code:
675        if (list_pipe || chline || simple_pline) {
676            breaks = loops;
677            errflag |= ERRFLAG_INT;
678            inerrflush();
679            check_cursh_sig(SIGINT);
680        }
681        lastval = 128 + SIGINT;
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?

The attached makes both "while do" and "do done" into parse errors; I
didn't want to try messing with the tokenizer, so better solutions are
welcome.

I mention tokenizing because in "for do" the string "do" is not a
token; "while do;" could conceivably mean to execute the command "do"
as the test condition.

[-- Attachment #2: while-do-done.txt --]
[-- Type: text/plain, Size: 659 bytes --]

diff --git a/Src/parse.c b/Src/parse.c
index b09c7989a..153633bb1 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1525,10 +1525,16 @@ par_while(int *cmplx)
     incmdpos = 1;
     while (tok == SEPER)
 	zshlex();
-    if (tok == DOLOOP) {
+    /*
+     * If the very first thing after "while" is "do",
+     * ecused has advanced only two positions.  This
+     * is not a valid while-do construction.
+     */
+    if (tok == DOLOOP && (ecused - oecused) > 2) {
 	zshlex();
 	par_save_list(cmplx);
-	if (tok != DONE)
+	/* As above but "do done" is not valid */
+	if (tok != DONE || (ecused - oecused) < 8)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 15:46   ` Bart Schaefer
@ 2021-05-16 16:15     ` Mikael Magnusson
  2021-05-16 16:22       ` Lawrence Velázquez
  2021-05-16 17:47       ` Bart Schaefer
  0 siblings, 2 replies; 14+ messages in thread
From: Mikael Magnusson @ 2021-05-16 16:15 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Arseny Maslennikov, Zsh hackers list

On 5/16/21, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sun, May 16, 2021 at 7:28 AM Bart Schaefer <schaefer@brasslantern.com>
> wrote:
>>
>> > Even more, if the user enters "while do; done" in an interactive zsh
>> > instance, the busy loop is not interruptible by ^C, ^\ or ^Z; the shell
>> > has to be killed via some external means.
>>
>> I can NOT reproduce this in the latest revision from git, but I can
>> reproduce it in zsh-5.8.
>
> Specifically, the shell is interruptible by ^C.  I haven't attempted
> to bisect where this was introduced; there are no obvious deltas to
> signals.c, loop.c, or parse.c to explain it.

I just updated to latest git and I still can't ^C the "while do;
done". I do have some local patches on top but nothing that
intentionally messes with anything related to this afaik...

> It is impossible to interrupt the parser with SIGINT.  zhandler is
> entered with signal queueing enabled; when signals are allowed again,
> zhandler is called again and we pass through this code:
> 675        if (list_pipe || chline || simple_pline) {
> 676            breaks = loops;
> 677            errflag |= ERRFLAG_INT;
> 678            inerrflush();
> 679            check_cursh_sig(SIGINT);
> 680        }
> 681        lastval = 128 + SIGINT;
> 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?
>
> The attached makes both "while do" and "do done" into parse errors; I
> didn't want to try messing with the tokenizer, so better solutions are
> welcome.

I use "do done" in production code so you can't remove that. I could
imagine someone using "while do" too, but I don't so I won't complain
about that part :). It is faster to not run the builtin "true" than it
is to run it, and it has been valid syntax all these years.

> I mention tokenizing because in "for do" the string "do" is not a
> token; "while do;" could conceivably mean to execute the command "do"
> as the test condition.


-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 16:15     ` Mikael Magnusson
@ 2021-05-16 16:22       ` Lawrence Velázquez
  2021-05-16 17:47       ` Bart Schaefer
  1 sibling, 0 replies; 14+ messages in thread
From: Lawrence Velázquez @ 2021-05-16 16:22 UTC (permalink / raw)
  To: Mikael Magnusson, Bart Schaefer; +Cc: Arseny Maslennikov, zsh-workers

On Sun, May 16, 2021, at 12:15 PM, Mikael Magnusson wrote:
> On 5/16/21, Bart Schaefer <schaefer@brasslantern.com> wrote:
> > The attached makes both "while do" and "do done" into parse errors; I
> > didn't want to try messing with the tokenizer, so better solutions are
> > welcome.
> 
> I use "do done" in production code so you can't remove that. I could
> imagine someone using "while do" too, but I don't so I won't complain
> about that part :). It is faster to not run the builtin "true" than it
> is to run it, and it has been valid syntax all these years.

It seems to agree with zshmisc(1) as well (a naïve reading of it, at least):

       A list is a sequence of zero or more sublists, in which each sublist is
       terminated by `;', `&', `&|', `&!', or a newline.

       [...]

       while list do list done
              Execute the do list as long as the while list returns a zero
              exit status.


-- 
vq


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16  9:16 'while do done' hangs interactive zsh Arseny Maslennikov
  2021-05-16 14:28 ` Bart Schaefer
@ 2021-05-16 16:43 ` Stephane Chazelas
  2021-05-16 18:02   ` Bart Schaefer
  1 sibling, 1 reply; 14+ messages in thread
From: Stephane Chazelas @ 2021-05-16 16:43 UTC (permalink / raw)
  To: Arseny Maslennikov; +Cc: zsh-workers

2021-05-16 12:16:24 +0300, Arseny Maslennikov:
> Hi everyone!
> 
> When zsh tries to execute "while do; done", it enters a busy loop:
> 
> % dash -c 'while do; done'
> dash: 1: Syntax error: "do" unexpected
> % bash -c 'while do; done'
> bash: -c: line 1: syntax error near unexpected token `do'
> bash: -c: line 1: `while do; done'
> % zsh -c 'while do; done' 	# never finishes/prompts by itself
> ^C
> zsh -c 'while do; done'  27,73s user 0,00s system 99% cpu 27,732 total 4k maxrss
> 
> Even more, if the user enters "while do; done" in an interactive zsh
> instance, the busy loop is not interruptible by ^C, ^\ or ^Z; the shell
> has to be killed via some external means.
> 
> To be fair, I have discovered the bug with the semicolon omitted ("while do done").
[...]

As far as I can tell, it works as documented.

while LIST do LIST done

LIST is not explicitely specified, but it does appear to be a
list of 0 or more pipelines. Or in other words any script.

So:

while do done

Runs the empty list of pipelines as long as the empty list of
pipelines is successful.

You'll see you can also do

if then echo the empty list is successful; fi

repeat 1000000 do done

myfunc() { }

if [ -e x ]; then else echo does not exist; fi

That does not even make zsh non-POSIX compliant, as those are
not valid POSIX sh syntax, so implementations are free to do
whatever they want.

If you want your *script* to be portable, you should not write:

while do echo yes; done

as a forever loop, as other shells require at least one pipeline
in the condition LIST (which to me just looks like an
arbitrary, unecessary limitation), but that does not mean shell
implementations have to return an error here.

-- 
Stephane






^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 16:15     ` Mikael Magnusson
  2021-05-16 16:22       ` Lawrence Velázquez
@ 2021-05-16 17:47       ` Bart Schaefer
  2021-05-16 18:23         ` Martijn Dekker
  1 sibling, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 17:47 UTC (permalink / raw)
  To: Zsh hackers list; +Cc: Arseny Maslennikov

[-- Attachment #1: Type: text/plain, Size: 1073 bytes --]

On Sun, May 16, 2021 at 9:15 AM Mikael Magnusson <mikachu@gmail.com> wrote:
>
> On 5/16/21, Bart Schaefer <schaefer@brasslantern.com> 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.

[-- Attachment #2: exec-errflag.txt --]
[-- Type: text/plain, Size: 934 bytes --]

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);
             }

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 16:43 ` 'while do done' hangs interactive zsh Stephane Chazelas
@ 2021-05-16 18:02   ` Bart Schaefer
  2021-05-16 18:25     ` Martijn Dekker
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 18:02 UTC (permalink / raw)
  To: Arseny Maslennikov, Zsh hackers list

On Sun, May 16, 2021 at 9:43 AM Stephane Chazelas <stephane@chazelas.org> wrote:
>
> while LIST do LIST done
>
> LIST is not explicitely specified, but it does appear to be a
> list of 0 or more pipelines. Or in other words any script.
>
[...]
>
> ... other shells require at least one pipeline
> in the condition LIST (which to me just looks like an
> arbitrary, unecessary limitation), but that does not mean shell
> implementations have to return an error here.

Bash requires at least one pipeline in the do-LIST as well.

Is this worth making into an emulation-mode thing, i.e., adding a
couple of more conditions to my while-do-done patch?

The documentation for CSH_JUNKIE_LOOPS could do with some updating as well.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 17:47       ` Bart Schaefer
@ 2021-05-16 18:23         ` Martijn Dekker
  2021-05-16 19:59           ` Bart Schaefer
  0 siblings, 1 reply; 14+ messages in thread
From: Martijn Dekker @ 2021-05-16 18:23 UTC (permalink / raw)
  To: zsh-workers

Op 16-05-21 om 19:47 schreef Bart Schaefer:
> Let's try the attached, then?

Interactive zsh with that patch still locks up on 'while do done' for 
me, requiring SIGKILL to terminate. This is on macOS 10.14.16 with 
Apple's version of clang 11.0.0.

-- 
||	modernish -- harness the shell
||	https://github.com/modernish/modernish
||
||	KornShell lives!
||	https://github.com/ksh93/ksh


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 18:02   ` Bart Schaefer
@ 2021-05-16 18:25     ` Martijn Dekker
  0 siblings, 0 replies; 14+ messages in thread
From: Martijn Dekker @ 2021-05-16 18:25 UTC (permalink / raw)
  To: zsh-workers

Op 16-05-21 om 20:02 schreef Bart Schaefer:
> Bash requires at least one pipeline in the do-LIST as well.
> 
> Is this worth making into an emulation-mode thing, i.e., adding a
> couple of more conditions to my while-do-done patch?

My understanding of the emulation mode is that it attempts to make the 
changes necessary to eliminate incompatibilities with the POSIX 
standard. This does not require disabling extensions that are compatible 
with it.

The two empty command lists in 'while do done' are both straightforward 
syntax errors in POSIX, so the extension to allow them is not 
incompatible with the standard; there's no syntactic clash with the 
POSIX equivalent, 'while :; do :; done'. So I see no need for the 
emulation mode to disallow empty command lists.

AFAIK there's only one shell with a POSIX mode that attempts to disallow 
(almost) everything not specified by the standard, and that's yash.

-- 
||	modernish -- harness the shell
||	https://github.com/modernish/modernish
||
||	KornShell lives!
||	https://github.com/ksh93/ksh


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 18:23         ` Martijn Dekker
@ 2021-05-16 19:59           ` Bart Schaefer
  2021-05-16 20:34             ` Peter Stephenson
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 19:59 UTC (permalink / raw)
  To: Zsh hackers list

On Sun, May 16, 2021 at 11:25 AM Martijn Dekker <martijn@inlv.org> wrote:
>
> Op 16-05-21 om 19:47 schreef Bart Schaefer:
> > Let's try the attached, then?
>
> Interactive zsh with that patch still locks up on 'while do done'

So this is MacOS:

% TRAPINT() { print Got INT }
% while do done
^CGot INT
^CGot INT
^CGot INT
^CGot INT
^CGot INT

That's exactly what also happens on Ubuntu.  But if I change that to:

% TRAPINT() { print Got INT; break }

Then on Ubuntu a ^C stops the loop, but on MacOS it does not.  This
implies that the value of the global "breaks" is not propagating into
execwhile() when set from the signal handler.  This may be an
optimization problem with clang?   Some random fiddling indicates that
the value of "errflag" may not be propagating out of the signal
handler either.

Indeed, this seems to fix it for MacOS:

diff --git a/Src/loop.c b/Src/loop.c
index aa733a2cb..db5b3e097 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -43,7 +43,7 @@ mod_export int contflag;
 /* # of break levels */

 /**/
-mod_export int breaks;
+mod_export volatile int breaks;

 /**/
 int

Do we need to worry about compilers that don't accept "volatile"?  I'd
suggest throwing "volatile" into the computed definition of
"mod_export" except I've forgotten whether there is such a thing as
declaring a function to be volatile.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: 'while do done' hangs interactive zsh
  2021-05-16 19:59           ` Bart Schaefer
@ 2021-05-16 20:34             ` Peter Stephenson
  2021-05-16 21:19               ` [PATCH] volatile declarations (was Re: 'while do done' hangs interactive zsh) Bart Schaefer
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Stephenson @ 2021-05-16 20:34 UTC (permalink / raw)
  To: zsh-workers

On Sun, 2021-05-16 at 12:59 -0700, Bart Schaefer wrote:
> Do we need to worry about compilers that don't accept "volatile"?

I think we lost the pre-ISO world some time ago now.  I can't believe
"volatile" is a problem.

pws



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] volatile declarations (was Re: 'while do done' hangs interactive zsh)
  2021-05-16 20:34             ` Peter Stephenson
@ 2021-05-16 21:19               ` Bart Schaefer
  2021-05-16 23:40                 ` Martijn Dekker
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2021-05-16 21:19 UTC (permalink / raw)
  To: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 236 bytes --]

On Sun, May 16, 2021 at 1:34 PM Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
>
> I think we lost the pre-ISO world some time ago now.  I can't believe
> "volatile" is a problem.

OK, see attached.  I hope I haven't missed any.

[-- Attachment #2: volatile.txt --]
[-- Type: text/plain, Size: 4906 bytes --]

diff --git a/Src/builtin.c b/Src/builtin.c
index a29eb49e4..a16fddcb7 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -5635,13 +5635,16 @@ bin_getopts(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int fun
  */
 
 /**/
-mod_export int
-exit_pending;
+mod_export volatile int exit_pending;
 
 /* Shell level at which we exit if exit_pending */
 /**/
-mod_export int
-exit_level;
+mod_export volatile int exit_level;
+
+/* we have printed a 'you have stopped (running) jobs.' message */
+
+/**/
+mod_export volatile int stopmsg;
 
 /* break, bye, continue, exit, logout, return -- most of these take   *
  * one numeric argument, and the other (logout) is related to return. *
@@ -5733,11 +5736,6 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func)
     return 0;
 }
 
-/* we have printed a 'you have stopped (running) jobs.' message */
-
-/**/
-mod_export int stopmsg;
-
 /* check to see if user has jobs running/stopped */
 
 /**/
diff --git a/Src/exec.c b/Src/exec.c
index 6f09e0d9f..49ff88b80 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -84,7 +84,7 @@ int nohistsave;
 /* error flag: bits from enum errflag_bits */
 
 /**/
-mod_export int errflag;
+mod_export volatile int errflag;
 
 /*
  * State of trap return value.  Value is from enum trap_state.
@@ -122,7 +122,7 @@ int subsh;
 /* != 0 if we have a return pending */
 
 /**/
-mod_export int retflag;
+mod_export volatile int retflag;
 
 /**/
 long lastval2;
@@ -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/loop.c b/Src/loop.c
index aa733a2cb..db5b3e097 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -43,7 +43,7 @@ mod_export int contflag;
 /* # of break levels */
  
 /**/
-mod_export int breaks;
+mod_export volatile int breaks;
 
 /**/
 int
diff --git a/Src/makepro.awk b/Src/makepro.awk
index 226d3f96b..f69660531 100644
--- a/Src/makepro.awk
+++ b/Src/makepro.awk
@@ -79,7 +79,7 @@ BEGIN {
 	    break
     }
     sub(/^ */, "", line)
-    match(line, /^((const|enum|mod_export|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
+    match(line, /^((const|enum|mod_export|static|struct|union|volatile) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
     dtype = substr(line, 1, RLENGTH)
     sub(/ *$/, "", dtype)
     if(" " dtype " " ~ / static /)
diff --git a/Src/params.c b/Src/params.c
index 20dfb5b5f..4f6b361f9 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -98,8 +98,10 @@ char *ifs,		/* $IFS         */
      *pwd;		/* $PWD         */
 
 /**/
-mod_export
-zlong lastval,		/* $?           */
+mod_export volatile zlong
+     lastval;		/* $?           */
+/**/
+mod_export zlong
      mypid,		/* $$           */
      lastpid,		/* $!           */
      zterm_columns,	/* $COLUMNS     */
diff --git a/Src/signals.c b/Src/signals.c
index 4adf03202..2c540f38f 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -53,7 +53,7 @@ mod_export Eprog siglists[VSIGCOUNT];
 /* Total count of trapped signals */
 
 /**/
-mod_export int nsigtrapped;
+mod_export volatile int nsigtrapped;
 
 /* Running an exit trap? */
 
@@ -72,20 +72,20 @@ static int exit_trap_posix;
 /* Variables used by signal queueing */
 
 /**/
-mod_export int queueing_enabled, queue_front, queue_rear;
+mod_export volatile int queueing_enabled, queue_front, queue_rear;
 /**/
 mod_export int signal_queue[MAX_QUEUE_SIZE];
 /**/
 mod_export sigset_t signal_mask_queue[MAX_QUEUE_SIZE];
 #ifdef DEBUG
 /**/
-mod_export int queue_in;
+mod_export volatile int queue_in;
 #endif
 
 /* Variables used by trap queueing */
 
 /**/
-mod_export int trap_queueing_enabled, trap_queue_front, trap_queue_rear;
+mod_export volatile int trap_queueing_enabled, trap_queue_front, trap_queue_rear;
 /**/
 mod_export int trap_queue[MAX_QUEUE_SIZE];
 
@@ -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);
             }
@@ -1266,19 +1266,19 @@ unqueue_traps(void)
 
 /* Are we already executing a trap? */
 /**/
-int intrap;
+volatile int intrap;
 
 /* Is the current trap a function? */
 
 /**/
-int trapisfunc;
+volatile int trapisfunc;
 
 /*
  * If the current trap is not a function, at what function depth
  * did the trap get called?
  */
 /**/
-int traplocallevel;
+volatile int traplocallevel;
 
 /*
  * sig is the signal number.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] volatile declarations (was Re: 'while do done' hangs interactive zsh)
  2021-05-16 21:19               ` [PATCH] volatile declarations (was Re: 'while do done' hangs interactive zsh) Bart Schaefer
@ 2021-05-16 23:40                 ` Martijn Dekker
  0 siblings, 0 replies; 14+ messages in thread
From: Martijn Dekker @ 2021-05-16 23:40 UTC (permalink / raw)
  To: zsh-workers

Op 16-05-21 om 23:19 schreef Bart Schaefer:
> On Sun, May 16, 2021 at 1:34 PM Peter Stephenson
> <p.w.stephenson@ntlworld.com> wrote:
>>
>> I think we lost the pre-ISO world some time ago now.  I can't believe
>> "volatile" is a problem.
> 
> OK, see attached.  I hope I haven't missed any.

That fixes it on my end.

-- 
||	modernish -- harness the shell
||	https://github.com/modernish/modernish
||
||	KornShell lives!
||	https://github.com/ksh93/ksh


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-05-16 23:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-16  9:16 'while do done' hangs interactive zsh Arseny Maslennikov
2021-05-16 14:28 ` Bart Schaefer
2021-05-16 15:46   ` Bart Schaefer
2021-05-16 16:15     ` Mikael Magnusson
2021-05-16 16:22       ` Lawrence Velázquez
2021-05-16 17:47       ` Bart Schaefer
2021-05-16 18:23         ` Martijn Dekker
2021-05-16 19:59           ` Bart Schaefer
2021-05-16 20:34             ` Peter Stephenson
2021-05-16 21:19               ` [PATCH] volatile declarations (was Re: 'while do done' hangs interactive zsh) Bart Schaefer
2021-05-16 23:40                 ` Martijn Dekker
2021-05-16 16:43 ` 'while do done' hangs interactive zsh Stephane Chazelas
2021-05-16 18:02   ` Bart Schaefer
2021-05-16 18:25     ` Martijn Dekker

zsh-workers

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/zsh-workers

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 zsh-workers zsh-workers/ http://inbox.vuxu.org/zsh-workers \
		zsh-workers@zsh.org
	public-inbox-index zsh-workers

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


code repositories for the project(s) associated with this inbox:

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

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git