From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20475 invoked by alias); 26 Apr 2017 19:34:40 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 41011 Received: (qmail 16820 invoked from network); 26 Apr 2017 19:34:40 -0000 X-Qmail-Scanner-Diagnostics: from know-smtprelay-omc-11.server.virginmedia.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(80.0.253.75):SA:0(-2.8/5.0):. Processed in 2.432949 secs); 26 Apr 2017 19:34:40 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.1 X-Envelope-From: p.w.stephenson@ntlworld.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _smtprelay.virginmedia.com designates 80.0.253.75 as permitted sender) X-Originating-IP: [86.21.219.59] X-Authenticated-User: p.w.stephenson@ntlworld.com X-Spam: 0 X-Authority: v=2.1 cv=cupm6AMi c=1 sm=1 tr=0 a=utowdAHh8RITBM/6U1BPxA==:117 a=utowdAHh8RITBM/6U1BPxA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=IkcTkHD0fZMA:10 a=r0xJ3ShlAAAA:8 a=efCYBKyIB_x-12hW5rgA:9 a=QEXdDO2ut3YA:10 a=WJ66ziG2ud5yTF66oKWO:22 Date: Wed, 26 Apr 2017 20:27:29 +0100 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: Call stack issues when running trap handler Message-ID: <20170426202729.12cf4bb8@ntlworld.com> In-Reply-To: <87efwlijrl.fsf@wirrsal.net> References: <87efwlijrl.fsf@wirrsal.net> X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ntlworld.com; s=meg.feb2017; t=1493234849; bh=F4pBvvAqsS597CsCSmJkrEMUb+neKiMG57WOUxdBI30=; h=Date:From:To:Subject:In-Reply-To:References; b=dT8UwuTw2AOEU/oh6gCAvwPiKPK8erzMlVu5AcgvtgnMPLExAWRlf/lU06WsuxRfK 1wHRTn6aqw1A+x/jTovDag9bDdyRF0lknXg4U/PL9FvRohqHB1HrIclv9kknH72qRh PRVZpaWYqfdMj4W65pEc6JmDy7gKNfd4RHg8jobUX1g+abgVVizbAIvyjPwBLZ7yXF k4oXOBXGbkj+TxQYLW44UMxsg6QtAGOQl6gEtiFUTtHD7srkGo66Ll0WeUNqK8gL68 VYL/c5EsSf2ktSoKhDpbhWYN1zREMueNsDjFnFpDTMl7Ew4idZ9SicMy/uahc09oKl yDjfwGfY81OnQ== On Fri, 21 Apr 2017 22:32:46 +0200 Sebastian Reu=C3=9Fe wrote: > I=E2=80=99ve noticed that under certain conditions, shell functions calle= d from > inside an exit trap handler appear to never return. E.g., running the > following code will only yield =C2=ABa=C2=BB as output, indicating that c= allee > =C2=ABechoa=C2=BB never returns control to the caller =C2=ABhandler=C2=BB. I've just re-read this and compared with the evidence and obviously I've misinterpreted it. When you said "never return", you meant it exited from that point (so never printed "b" but did leave the shell nonetheless). I interpreted this as saying it got stuck in that function, but that obviously isn't what you mean. This I can fix. If anyone knows whether I need to distinguish in any of the following between EXIT traps for functions and the shell as a whole, feel free to tell me. I'm assuming it's going to be too arcane to worry about. pws diff --git a/Src/builtin.c b/Src/builtin.c index b2e552d..ff07b04 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5509,8 +5509,11 @@ bin_break(char *name, char **argv, UNUSED(Options op= s), int func) * * If we are forked, we exit the shell at the function depth * at which we became a subshell, hence the comparison. + * + * If we *are* in an EXIT trap... give this all up as + * a bad job. */ - if (stopmsg || (zexit(0,2), !stopmsg)) { + if ((stopmsg || (zexit(0,2), !stopmsg)) && !in_exit_trap) { retflag =3D 1; breaks =3D loops; exit_pending =3D (num << 1) | 1; diff --git a/Src/exec.c b/Src/exec.c index 978a32d..e0fc544 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5688,8 +5688,11 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noret= urnval) * the only likely case where we need that second test is * when we have an "always" block. The endparamscope() has * already happened, hence the "+1" here. + * + * If we are in an exit trap, finish it first... we wouldn't set + * exit_pending if we were already in one. */ - if (exit_pending && exit_level >=3D locallevel+1) { + if (exit_pending && exit_level >=3D locallevel+1 && !in_exit_trap) { if (locallevel > forklevel) { /* Still functions to return: force them to do so. */ retflag =3D 1; diff --git a/Src/signals.c b/Src/signals.c index 68a7ae3..cad40f4 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -55,6 +55,11 @@ mod_export Eprog siglists[VSIGCOUNT]; /**/ mod_export int nsigtrapped; =20 +/* Running an exit trap? */ + +/**/ +int in_exit_trap; + /* * Flag that exit trap has been set in POSIX mode. * The setter's expectation is therefore that it is run @@ -1435,7 +1440,13 @@ dotrap(int sig) =20 dont_queue_signals(); =20 + if (sig =3D=3D SIGEXIT) + ++in_exit_trap; + dotrapargs(sig, sigtrapped+sig, funcprog); =20 + if (sig =3D=3D SIGEXIT) + --in_exit_trap; + restore_queue_signals(q); }