From patchwork Sun Dec 2 14:53:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10708047 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC92413AF for ; Sun, 2 Dec 2018 14:53:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8FA2B2A88D for ; Sun, 2 Dec 2018 14:53:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 838B029E14; Sun, 2 Dec 2018 14:53:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AFBF2A436 for ; Sun, 2 Dec 2018 14:53:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725865AbeLBOxj (ORCPT ); Sun, 2 Dec 2018 09:53:39 -0500 Received: from orcrist.hmeau.com ([104.223.48.154]:38160 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725856AbeLBOxj (ORCPT ); Sun, 2 Dec 2018 09:53:39 -0500 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1gTT7m-0001GG-V7; Sun, 02 Dec 2018 22:53:35 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1gTT7k-0002Ec-AL; Sun, 02 Dec 2018 22:53:32 +0800 Date: Sun, 2 Dec 2018 22:53:32 +0800 From: Herbert Xu To: Martijn Dekker Cc: DASH shell mailing list Subject: [v2 PATCH] eval: Only restore exit status on exit/return Message-ID: <20181202145332.snc5z6tvisnulc7q@gondor.apana.org.au> References: <20181129113353.kx5ccakbvwnk6ptr@gondor.apana.org.au> <20181129144852.zurgvf367mmtmmsh@gondor.apana.org.au> <7272abdb-fa42-f499-6408-4a3a7c3c408e@inlv.org> <20181201084539.hat5wey2ho7fi6id@gondor.apana.org.au> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181201084539.hat5wey2ho7fi6id@gondor.apana.org.au> User-Agent: NeoMutt/20170113 (1.7.2) Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Sat, Dec 01, 2018 at 04:45:39PM +0800, Herbert Xu wrote: > > Hmm, I think this breaks the following case which used to work: > > dash -c 'trap "(:; exit) && echo BUG" EXIT; false' > > I know this makes no sense but almost every other shell does it > this way. Here is a new patch that fixes the reported issue for both signal traps and the EXIT trap. ---8<--- We unconditionally restore the saved status in exitreset, which is incorrect as we only want to do it for exitcmd and returncmd. This patch fixes the problem by introducing EXEND. Reported-by: Martijn Dekker Fixes: da30b4b78769 ("[BUILTIN] Exit without arguments in a trap...") Signed-off-by: Herbert Xu diff --git a/src/error.h b/src/error.h index 9630b56..94e30a2 100644 --- a/src/error.h +++ b/src/error.h @@ -66,7 +66,8 @@ extern int exception; /* exceptions */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ -#define EXEXIT 4 /* exit the shell */ +#define EXEND 3 /* exit the shell */ +#define EXEXIT 4 /* exit the shell via exitcmd */ /* diff --git a/src/eval.c b/src/eval.c index 546ee1b..3cea2a3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -114,12 +114,13 @@ STATIC const struct builtincmd bltin = { INCLUDE "eval.h" EXITRESET { - evalskip = 0; - loopnest = 0; if (savestatus >= 0) { - exitstatus = savestatus; + if (exception == EXEXIT || evalskip == SKIPFUNCDEF) + exitstatus = savestatus; savestatus = -1; } + evalskip = 0; + loopnest = 0; } #endif @@ -314,7 +315,7 @@ out: if (flags & EV_EXIT) { exexit: - exraise(EXEXIT); + exraise(EXEND); } return exitstatus; diff --git a/src/exec.c b/src/exec.c index 9d0215a..87354d4 100644 --- a/src/exec.c +++ b/src/exec.c @@ -143,7 +143,7 @@ shellexec(char **argv, const char *path, int idx) exitstatus = exerrno; TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", argv[0], e, suppressint )); - exerror(EXEXIT, "%s: %s", argv[0], errmsg(e, E_EXEC)); + exerror(EXEND, "%s: %s", argv[0], errmsg(e, E_EXEC)); /* NOTREACHED */ } diff --git a/src/main.c b/src/main.c index 6d53e00..6b3a090 100644 --- a/src/main.c +++ b/src/main.c @@ -111,7 +111,7 @@ main(int argc, char **argv) e = exception; s = state; - if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) + if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) exitshell(); reset(); diff --git a/src/trap.c b/src/trap.c index ab0ecd4..64917fc 100644 --- a/src/trap.c +++ b/src/trap.c @@ -397,8 +397,10 @@ exitshell(void) trap[0] = NULL; evalskip = 0; evalstring(p, 0); + evalskip = SKIPFUNCDEF; } out: + exitreset(); /* * Disable job control so that whoever had the foreground before we * started can get it back. @@ -406,7 +408,7 @@ out: if (likely(!setjmp(loc.loc))) setjobctl(0); flushall(); - _exit(savestatus); + _exit(exitstatus); /* NOTREACHED */ }