Re: Loops and pipes
Philippe Altherr <[email protected]> Tue, 4 Aug 2026 17:11:25 +0200
| Newsgroups | gmane.comp.shells.zsh.devel |
|---|---|
| Message-ID | <CAGdYchtnz_ti5BSmyUFGQr2y3UYE5OCAi6PE9+nsh==rHbf4CQ@mail.gmail.com> |
--00000000000039ff5406583a1242 Content-Type: multipart/alternative; boundary="00000000000039ff5306583a1240" --00000000000039ff5306583a1240 Content-Type: text/plain; charset="UTF-8" > > Making it an error is quite simple: > > diff --git a/Src/exec.c b/Src/exec.c > index 5f849db63..2e6684c96 100644 > --- a/Src/exec.c > +++ b/Src/exec.c > @@ -1258,6 +1258,7 @@ entersubsh(int flags, struct entersubsh_ret *retp) > clearjobtab(monitor); > get_usage(); > forklevel = locallevel; > + loops = 0; > } > > /* execute a string */ > That works but for break/continue statements that are in a subshell of their first enclosing loop it produces rather confusing error messages stating that there are no loops. Here is a patch that avoids that: - Forbid break/continue in subshells <https://github.com/zsh-users/zsh/compare/master...paltherr:zsh:no-loop-control-from-subshell> And here is a further patch that also checks that the break/continue statements don't escape past the available loops: - Forbid escaping past all enclosing loops in the same subshell <https://github.com/paltherr/zsh/compare/forbid-escaping-past-all-loops-start...paltherr:zsh:forbid-escaping-past-all-loops> The description of "continue n" states that it breaks out of n-1 loops and resumes the nth loop but if there are m<n loops then it behaves as "continue m", which is rather unexpected. The second patch avoids that by making "continue n" (as well as "break n") illegal if n is greater than the number of enclosing loops (started in the same subshell as the break/continue statement). Philippe --00000000000039ff5306583a1240 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_quote gmail_quote_container"><blockquo= te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px = solid rgb(204,204,204);padding-left:1ex">Making it an error is quite simple= :<br> <br> diff --git a/Src/exec.c b/Src/exec.c<br> index 5f849db63..2e6684c96 100644<br> --- a/Src/exec.c<br> +++ b/Src/exec.c<br> @@ -1258,6 +1258,7 @@ entersubsh(int flags, struct entersubsh_ret *retp)<br= > =C2=A0 =C2=A0 =C2=A0 =C2=A0 clearjobtab(monitor);<br> =C2=A0 =C2=A0 =C2=A0get_usage();<br> =C2=A0 =C2=A0 =C2=A0forklevel =3D locallevel;<br> +=C2=A0 =C2=A0 loops =3D 0;<br> =C2=A0}<br> <br> =C2=A0/* execute a string */<br></blockquote><div><br></div><div>That works= but=C2=A0<span style=3D"background-color:transparent">for break/continue s= tatements that are in a subshell of their first enclosing loop it produces= =C2=A0</span><span style=3D"background-color:transparent">rather confusing = error messages stating that there are no loops. Here is a patch that avoids= that:</span></div><div><span style=3D"background-color:transparent"><br></= span></div><div>- <a href=3D"https://github.com/zsh-users/zsh/compare/maste= r...paltherr:zsh:no-loop-control-from-subshell">Forbid break/continue in su= bshells</a><span style=3D"background-color:transparent"></span></div><div><= br></div><div>And here is a further patch that also checks that the=C2=A0<s= pan style=3D"background-color:transparent">break/continue statements don= 9;t escape past the available loops:</span></div><div><span style=3D"backgr= ound-color:transparent"><br></span></div><div>- <a href=3D"https://github.c= om/paltherr/zsh/compare/forbid-escaping-past-all-loops-start...paltherr:zsh= :forbid-escaping-past-all-loops">Forbid escaping past all enclosing loops i= n the same subshell</a><span style=3D"background-color:transparent"></span>= </div><div><br></div><div>The description of "continue n" states = that it breaks out of n-1 loops and resumes the nth loop but if there are m= <n loops then it behaves as "continue m", which is rather unex= pected. The second patch avoids that by making=C2=A0<span style=3D"backgrou= nd-color:transparent">"continue n" (as well as "break n"= ;) illegal if n is greater than the number of enclosing loops (started in t= he same subshell as the=C2=A0</span>break/continue statement<span style=3D"= background-color:transparent">).</span></div><div><br></div><div>Philippe</= div><div><br></div></div></div> --00000000000039ff5306583a1240-- --00000000000039ff5406583a1242 Content-Type: text/plain; charset="US-ASCII"; name="no-loop-control-from-subshell.txt" Content-Disposition: attachment; filename="no-loop-control-from-subshell.txt" Content-Transfer-Encoding: base64 Content-ID: <f_msesp7nn0> X-Attachment-Id: f_msesp7nn0 ZGlmZiAtLWdpdCBhL1NyYy9idWlsdGluLmMgYi9TcmMvYnVpbHRpbi5jCmluZGV4IGUzNWQ3ZmUy Yy4uMTBjNjRkM2M4IDEwMDY0NAotLS0gYS9TcmMvYnVpbHRpbi5jCisrKyBiL1NyYy9idWlsdGlu LmMKQEAgLTU4MTQsMjQgKzU4MTQsMjIgQEAgYmluX2JyZWFrKGNoYXIgKm5hbWUsIGNoYXIgKiph cmd2LCBVTlVTRUQoT3B0aW9ucyBvcHMpLCBpbnQgZnVuYykKIAludW1wID0gMTsKICAgICB9CiAK LSAgICBpZiAobnVtcCA+IDAgJiYgKGZ1bmMgPT0gQklOX0NPTlRJTlVFIHx8IGZ1bmMgPT0gQklO X0JSRUFLKSAmJiBudW0gPD0gMCkgewotCXplcnJuYW0obmFtZSwgImFyZ3VtZW50IGlzIG5vdCBw b3NpdGl2ZTogJWQiLCBudW0pOwotCXJldHVybiAxOwotICAgIH0KLQogICAgIHN3aXRjaCAoZnVu YykgewogICAgIGNhc2UgQklOX0NPTlRJTlVFOgotCWlmICghbG9vcHMpIHsgICAvKiBjb250aW51 ZSBpcyBvbmx5IHBlcm1pdHRlZCBpbiBsb29wcyAqLwotCSAgICB6ZXJybmFtKG5hbWUsICJub3Qg aW4gd2hpbGUsIHVudGlsLCBzZWxlY3QsIG9yIHJlcGVhdCBsb29wIik7CisgICAgY2FzZSBCSU5f QlJFQUs6CisJbnVtID0gbnVtcCA/IG51bSA6IDE7CisJaWYgKG51bSA8PSAwKSB7CisJICAgIHpl cnJuYW0obmFtZSwgImFyZ3VtZW50IGlzIG5vdCBwb3NpdGl2ZTogJWQiLCBudW0pOwogCSAgICBy ZXR1cm4gMTsKIAl9Ci0JY29udGZsYWcgPSAxOyAvKiBGQUxMVEhST1VHSCAqLwotICAgIGNhc2Ug QklOX0JSRUFLOgotCWlmICghbG9vcHMpIHsgICAvKiBicmVhayBpcyBvbmx5IHBlcm1pdHRlZCBp biBsb29wcyAqLwotCSAgICB6ZXJybmFtKG5hbWUsICJub3QgaW4gd2hpbGUsIHVudGlsLCBzZWxl Y3QsIG9yIHJlcGVhdCBsb29wIik7CisJaWYgKCFsb29wcykgeyAgIC8qIGJyZWFrL2NvbnRpbnVl IG9ubHkgcGVybWl0dGVkIGluIGxvb3BzICovCisJICAgIHplcnJuYW0obmFtZSwgYW5jZXN0b3Jf bG9vcHMKKwkJICAgID8gIm5vdCBpbiBzYW1lIHN1YnNoZWxsIGFzIGZpcnN0IGVuY2xvc2luZyBs b29wIgorCQkgICAgOiAibm90IGluIGZvciwgd2hpbGUsIHVudGlsLCBzZWxlY3QsIG9yIHJlcGVh dCBsb29wIik7CiAJICAgIHJldHVybiAxOwogCX0KLQlicmVha3MgPSBudW1wID8gbWluaW11bShu dW0sbG9vcHMpIDogMTsKKwljb250ZmxhZyA9IGZ1bmMgPT0gQklOX0NPTlRJTlVFOworCWJyZWFr cyA9IG1pbmltdW0obnVtLCBsb29wcyk7CiAJYnJlYWs7CiAgICAgY2FzZSBCSU5fUkVUVVJOOgog CWlmICgoaXNzZXQoSU5URVJBQ1RJVkUpICYmIGlzc2V0KFNISU5TVERJTikpCmRpZmYgLS1naXQg YS9TcmMvZXhlYy5jIGIvU3JjL2V4ZWMuYwppbmRleCA1Zjg0OWRiNjMuLjk0ZjFiNzM1YyAxMDA2 NDQKLS0tIGEvU3JjL2V4ZWMuYworKysgYi9TcmMvZXhlYy5jCkBAIC0xMjU4LDYgKzEyNTgsOCBA QCBlbnRlcnN1YnNoKGludCBmbGFncywgc3RydWN0IGVudGVyc3Vic2hfcmV0ICpyZXRwKQogCWNs ZWFyam9idGFiKG1vbml0b3IpOwogICAgIGdldF91c2FnZSgpOwogICAgIGZvcmtsZXZlbCA9IGxv Y2FsbGV2ZWw7CisgICAgYW5jZXN0b3JfbG9vcHMgKz0gbG9vcHM7CisgICAgbG9vcHMgPSAwOwog fQogCiAvKiBleGVjdXRlIGEgc3RyaW5nICovCmRpZmYgLS1naXQgYS9TcmMvaW5pdC5jIGIvU3Jj L2luaXQuYwppbmRleCBkMmI5N2RhZmYuLmM1ZTkxNWJiMSAxMDA2NDQKLS0tIGEvU3JjL2luaXQu YworKysgYi9TcmMvaW5pdC5jCkBAIC0xMzI1LDcgKzEzMjUsNyBAQCBzZXR1cHZhbHMoY2hhciAq Y21kLCBjaGFyICpydW5zY3JpcHQsIGNoYXIgKnpzaF9uYW1lKQogICAgIH0KICNlbmRpZgogCi0g ICAgYnJlYWtzID0gbG9vcHMgPSAwOworICAgIGJyZWFrcyA9IGNvbnRmbGFnID0gbG9vcHMgPSBh bmNlc3Rvcl9sb29wcyA9IDA7CiAgICAgbGFzdG1haWxjaGVjayA9IHptb25vdGltZShOVUxMKTsK ICAgICBsb2NhbGxldmVsID0gc291cmNlbGV2ZWwgPSAwOwogICAgIHNmY29udGV4dCA9IFNGQ19O T05FOwpkaWZmIC0tZ2l0IGEvU3JjL2xvb3AuYyBiL1NyYy9sb29wLmMKaW5kZXggMzUxZWRkZTg5 Li42NmRhZDA1ZjggMTAwNjQ0Ci0tLSBhL1NyYy9sb29wLmMKKysrIGIvU3JjL2xvb3AuYwpAQCAt MzAsMTggKzMwLDIzIEBACiAjaW5jbHVkZSAienNoLm1kaCIKICNpbmNsdWRlICJsb29wLnBybyIK IAotLyogIyBvZiBuZXN0ZWQgbG9vcHMgd2UgYXJlIGluICovCi0gCisvKiAjIG9mIG5lc3RlZCBs b29wcyB3ZSBhcmUgaW4gc3RhcnRlZCBpbiBhbmNlc3RvciBzdWJzaGVsbHMgKi8KKworLyoqLwor aW50IGFuY2VzdG9yX2xvb3BzOworCisvKiAjIG9mIG5lc3RlZCBsb29wcyB3ZSBhcmUgaW4gc3Rh cnRlZCBpbiB0aGUgY3VycmVudCBzdWJzaGVsbCAqLworCiAvKiovCiBpbnQgbG9vcHM7Ci0gCi0v KiAjIG9mIGNvbnRpbnVlIGxldmVscyAqLwotIAorCisvKiB3aGV0aGVyIHRvIGNvbnRpbnVlIGlu c3RlYWQgb2YgYnJlYWsgb24gdGhlIGxhc3QgYnJlYWsgbGV2ZWwgKi8KKwogLyoqLwogbW9kX2V4 cG9ydCBpbnQgY29udGZsYWc7Ci0gCisKIC8qICMgb2YgYnJlYWsgbGV2ZWxzICovCi0gCisKIC8q Ki8KIG1vZF9leHBvcnQgdm9sYXRpbGUgaW50IGJyZWFrczsKIApkaWZmIC0tZ2l0IGEvVGVzdC9B MDdjb250cm9sLnp0c3QgYi9UZXN0L0EwN2NvbnRyb2wuenRzdAppbmRleCBiMWEyNDg3MzIuLmNm NzBkNDZmZSAxMDA2NDQKLS0tIGEvVGVzdC9BMDdjb250cm9sLnp0c3QKKysrIGIvVGVzdC9BMDdj b250cm9sLnp0c3QKQEAgLTI4LDcgKzI4LDE4IEBACiAgIH0KICAgZm4nCiAxOmNvbnRpbnVlIG91 dHNpZGUgbG9vcAotP2ZuOmNvbnRpbnVlOjE6IG5vdCBpbiB3aGlsZSwgdW50aWwsIHNlbGVjdCwg b3IgcmVwZWF0IGxvb3AKKz9mbjpjb250aW51ZToxOiBub3QgaW4gZm9yLCB3aGlsZSwgdW50aWws IHNlbGVjdCwgb3IgcmVwZWF0IGxvb3AKKworICBmb3IgeCBpbiBhIGIgYzsgZG8KKyAgICAoIGVj aG8gJHg6YmVmb3JlOyBjb250aW51ZSAyPiYxOyBlY2hvICR4OmFmdGVyICkKKyAgZG9uZQorMTpj b250aW51ZSBpbiBzdWJzaGVsbAorPmE6YmVmb3JlCis+KGV2YWwpOmNvbnRpbnVlOjI6IG5vdCBp biBzYW1lIHN1YnNoZWxsIGFzIGZpcnN0IGVuY2xvc2luZyBsb29wCis+YjpiZWZvcmUKKz4oZXZh bCk6Y29udGludWU6Mjogbm90IGluIHNhbWUgc3Vic2hlbGwgYXMgZmlyc3QgZW5jbG9zaW5nIGxv b3AKKz5jOmJlZm9yZQorPihldmFsKTpjb250aW51ZToyOiBub3QgaW4gc2FtZSBzdWJzaGVsbCBh cyBmaXJzdCBlbmNsb3NpbmcgbG9vcAogCiAgIGZvciBvdXRlciBpbiAwIDEgMiAzOyBkbwogICAg IHByaW50IG91dGVyICRvdXRlcgo= --00000000000039ff5406583a1242 Content-Type: text/plain; charset="US-ASCII"; name="forbid-escaping-past-all-loops.txt" Content-Disposition: attachment; filename="forbid-escaping-past-all-loops.txt" Content-Transfer-Encoding: base64 Content-ID: <f_msesphs61> X-Attachment-Id: f_msesphs61 ZGlmZiAtLWdpdCBhL1NyYy9idWlsdGluLmMgYi9TcmMvYnVpbHRpbi5jCmluZGV4IDEwYzY0ZDNj OC4uNDllZmZiMjJiIDEwMDY0NAotLS0gYS9TcmMvYnVpbHRpbi5jCisrKyBiL1NyYy9idWlsdGlu LmMKQEAgLTU4MjIsMTAgKzU4MjIsMjAgQEAgYmluX2JyZWFrKGNoYXIgKm5hbWUsIGNoYXIgKiph cmd2LCBVTlVTRUQoT3B0aW9ucyBvcHMpLCBpbnQgZnVuYykKIAkgICAgemVycm5hbShuYW1lLCAi YXJndW1lbnQgaXMgbm90IHBvc2l0aXZlOiAlZCIsIG51bSk7CiAJICAgIHJldHVybiAxOwogCX0K LQlpZiAoIWxvb3BzKSB7ICAgLyogYnJlYWsvY29udGludWUgb25seSBwZXJtaXR0ZWQgaW4gbG9v cHMgKi8KLQkgICAgemVycm5hbShuYW1lLCBhbmNlc3Rvcl9sb29wcwotCQkgICAgPyAibm90IGlu IHNhbWUgc3Vic2hlbGwgYXMgZmlyc3QgZW5jbG9zaW5nIGxvb3AiCi0JCSAgICA6ICJub3QgaW4g Zm9yLCB3aGlsZSwgdW50aWwsIHNlbGVjdCwgb3IgcmVwZWF0IGxvb3AiKTsKKwlpZiAobnVtID4g bG9vcHMpIHsgICAvKiBicmVhay9jb250aW51ZSBvbmx5IHBlcm1pdHRlZCBpbiBsb29wcyAqLwor CSAgICBpZiAoIWxvb3BzICYmICFhbmNlc3Rvcl9sb29wcykKKwkJemVycm5hbShuYW1lLAorCQkJ Im5vdCBpbiBmb3IsIHdoaWxlLCB1bnRpbCwgc2VsZWN0LCBvciByZXBlYXQgbG9vcCIpOworCSAg ICBlbHNlIGlmIChudW0gPiBsb29wcyArIGFuY2VzdG9yX2xvb3BzKQorCQl6ZXJybmFtKG5hbWUs CisJCQkibm90IGluICVkIGZvciwgd2hpbGUsIHVudGlsLCBzZWxlY3QsIG9yIHJlcGVhdCBsb29w cyIsCisJCQludW0pOworCSAgICBlbHNlIGlmICghbG9vcHMpCisJCXplcnJuYW0obmFtZSwgIm5v dCBpbiBzYW1lIHN1YnNoZWxsIGFzIGZpcnN0IGVuY2xvc2luZyBsb29wIik7CisJICAgIGVsc2UK KwkJemVycm5hbShuYW1lLAorCQkJIm5vdCBpbiBzYW1lIHN1YnNoZWxsIGFzIGZpcnN0ICVkIGVu Y2xvc2luZyBsb29wcyIsCisJCQludW0pOwogCSAgICByZXR1cm4gMTsKIAl9CiAJY29udGZsYWcg PSBmdW5jID09IEJJTl9DT05USU5VRTsKZGlmZiAtLWdpdCBhL1Rlc3QvQTA3Y29udHJvbC56dHN0 IGIvVGVzdC9BMDdjb250cm9sLnp0c3QKaW5kZXggY2Y3MGQ0NmZlLi5hZGI2NzZmMjMgMTAwNjQ0 Ci0tLSBhL1Rlc3QvQTA3Y29udHJvbC56dHN0CisrKyBiL1Rlc3QvQTA3Y29udHJvbC56dHN0CkBA IC0zMCw2ICszMCwyMSBAQAogMTpjb250aW51ZSBvdXRzaWRlIGxvb3AKID9mbjpjb250aW51ZTox OiBub3QgaW4gZm9yLCB3aGlsZSwgdW50aWwsIHNlbGVjdCwgb3IgcmVwZWF0IGxvb3AKIAorICAk WlRTVF90ZXN0ZGlyLy4uL1NyYy96c2ggLWZjICcKKyAgICBmb3IgeCBpbiBhIGIgYzsgZG8KKyAg ICAgIGZvciB5IGluIGQgZSBmOyBkbworICAgICAgICBlY2hvICIkeCR5OmJlZm9yZSIKKyAgICAg ICAgY29udGludWUgMworICAgICAgICBlY2hvICIkeCR5OmFmdGVyIgorICAgICAgZG9uZQorICAg ICAgZWNobyAiJHgtOmFmdGVyIgorICAgIGRvbmUKKyAgICBlY2hvICItLTphZnRlciIKKyAgJwor MTpjb250aW51ZSBiZXlvbmQgYWxsIGVuY2xvc2luZyBsb29wcworPmFkOmJlZm9yZQorP3pzaDpj b250aW51ZTo1OiBub3QgaW4gMyBmb3IsIHdoaWxlLCB1bnRpbCwgc2VsZWN0LCBvciByZXBlYXQg bG9vcHMKKwogICBmb3IgeCBpbiBhIGIgYzsgZG8KICAgICAoIGVjaG8gJHg6YmVmb3JlOyBjb250 aW51ZSAyPiYxOyBlY2hvICR4OmFmdGVyICkKICAgZG9uZQpAQCAtNDEsNiArNTYsMzEgQEAKID5j OmJlZm9yZQogPihldmFsKTpjb250aW51ZToyOiBub3QgaW4gc2FtZSBzdWJzaGVsbCBhcyBmaXJz dCBlbmNsb3NpbmcgbG9vcAogCisgIGZvciB4IGluIGEgYiBjOyBkbworICAgICgKKyAgICAgIGZv ciB5IGluIGQgZSBmOyBkbworICAgICAgICBlY2hvICIkeCR5OmJlZm9yZSIKKyAgICAgICAgY29u dGludWUgMiAyPiYxCisgICAgICAgIGVjaG8gIiR4JHk6YWZ0ZXIiCisgICAgICBkb25lCisgICAg ICBlY2hvICIkeC06YWZ0ZXIxIgorICAgICkKKyAgICBlY2hvICIkeC06YWZ0ZXIyIgorICBkb25l CisgIGVjaG8gIi0tOmFmdGVyIgorMDpjb250aW51ZSBiZXlvbmQgYWxsIGVuY2xvc2luZyBsb29w cworPmFkOmJlZm9yZQorPihldmFsKTpjb250aW51ZTo1OiBub3QgaW4gc2FtZSBzdWJzaGVsbCBh cyBmaXJzdCAyIGVuY2xvc2luZyBsb29wcworPmEtOmFmdGVyMgorPmJkOmJlZm9yZQorPihldmFs KTpjb250aW51ZTo1OiBub3QgaW4gc2FtZSBzdWJzaGVsbCBhcyBmaXJzdCAyIGVuY2xvc2luZyBs b29wcworPmItOmFmdGVyMgorPmNkOmJlZm9yZQorPihldmFsKTpjb250aW51ZTo1OiBub3QgaW4g c2FtZSBzdWJzaGVsbCBhcyBmaXJzdCAyIGVuY2xvc2luZyBsb29wcworPmMtOmFmdGVyMgorPi0t OmFmdGVyCisKKwogICBmb3Igb3V0ZXIgaW4gMCAxIDIgMzsgZG8KICAgICBwcmludCBvdXRlciAk b3V0ZXIKICAgICBmb3IgaW5uZXIgaW4gMCAxIDIgMzsgZG8K --00000000000039ff5406583a1242--