zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh-workers@zsh.org
Subject: Re: Call stack issues when running trap handler
Date: Wed, 26 Apr 2017 20:27:29 +0100	[thread overview]
Message-ID: <20170426202729.12cf4bb8@ntlworld.com> (raw)
In-Reply-To: <87efwlijrl.fsf@wirrsal.net>

On Fri, 21 Apr 2017 22:32:46 +0200
Sebastian Reuße <seb@wirrsal.net> wrote:
> I’ve noticed that under certain conditions, shell functions called from
> inside an exit trap handler appear to never return. E.g., running the
> following code will only yield «a» as output, indicating that callee
> «echoa» never returns control to the caller «handler».

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 ops), 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 = 1;
 		breaks = loops;
 		exit_pending = (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 noreturnval)
      * 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 >= locallevel+1) {
+    if (exit_pending && exit_level >= locallevel+1 && !in_exit_trap) {
 	if (locallevel > forklevel) {
 	    /* Still functions to return: force them to do so. */
 	    retflag = 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;
 
+/* 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)
 
     dont_queue_signals();
 
+    if (sig == SIGEXIT)
+	++in_exit_trap;
+
     dotrapargs(sig, sigtrapped+sig, funcprog);
 
+    if (sig == SIGEXIT)
+	--in_exit_trap;
+
     restore_queue_signals(q);
 }


  parent reply	other threads:[~2017-04-26 19:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20170421203315epcas2p2bcf3453e9998002d444d4fa02a87b58e@epcas2p2.samsung.com>
2017-04-21 20:32 ` Sebastian Reuße
2017-04-21 22:19   ` Bart Schaefer
2017-04-24  9:00   ` Peter Stephenson
2017-04-24 16:16     ` Bart Schaefer
2017-04-24 17:17       ` Peter Stephenson
2017-04-24 17:39         ` Bart Schaefer
2017-04-26 19:27   ` Peter Stephenson [this message]
2017-04-26 19:52     ` Peter Stephenson
2017-04-26 21:15       ` Bart Schaefer
2017-05-11  7:58       ` Sebastian Reuße

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=20170426202729.12cf4bb8@ntlworld.com \
    --to=p.w.stephenson@ntlworld.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).