NetBSD Problem Report #6764
Received: (qmail 26913 invoked from network); 8 Jan 1999 02:27:45 -0000
Message-Id: <199901080225.VAA14271@bill-the-cat.mit.edu>
Date: Thu, 7 Jan 1999 21:25:09 -0500 (EST)
From: "Charles M. Hannum" <root@ihack.net>
Reply-To: mycroft@netbsd.org
To: gnats-bugs@gnats.netbsd.org
Subject: `trap 0' does not work in ksh subshells
X-Send-Pr-Version: 3.95
>Number: 6764
>Category: bin
>Synopsis: `trap 0' does not work in ksh subshells
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jan 07 18:35:01 +0000 1999
>Closed-Date: Sun Oct 06 11:09:55 +0000 2013
>Last-Modified: Sun Oct 06 11:09:55 +0000 2013
>Originator: Charles M. Hannum
>Release: 1.3I and earlier
>Organization:
dis
>Environment:
System: NetBSD zygorthian-space-raiders.mit.edu 1.3H NetBSD 1.3H (ZYGORTHIAN-SPACE-RAIDERS) #5: Sun Nov 8 20:58:49 EST 1998 mycroft@zygorthian-space-raiders.mit.edu:/u2/src/sys/arch/i386/compile/ZYGORTHIAN-SPACE-RAIDERS i386
>Description:
`trap foo 0' is supposed to execute `foo' when the shell
exits. This works correctly with subshells in /bin/sh but not
in /bin/ksh. This is a serious compatibility problem with the
original Korn shell.
>How-To-Repeat:
The following script should output `win'. It doesn't.
#!/bin/ksh
(trap 'echo win' 0)
>Fix:
Not analyzed.
>Release-Note:
>Audit-Trail:
From: Kevin Schoedel <kevin@quipu.waterloo-rdp.on.ca>
To: gnats-bugs@gnats.netbsd.org
Cc: pdksh@cs.mun.ca, "Charles M. Hannum" <root@ihack.net>
Subject: Re: bin/6764: `trap 0' does not work in ksh subshells
Date: Sun, 10 Jan 1999 21:53:40 -0500
In <199901080225.VAA14271@bill-the-cat.mit.edu>, "Charles M. Hannum" <root@ihack.net> wrote:
>>Description:
>
> `trap foo 0' is supposed to execute `foo' when the shell
> exits. This works correctly with subshells in /bin/sh but not
> in /bin/ksh. This is a serious compatibility problem with the
> original Korn shell.
>
>>How-To-Repeat:
>
> The following script should output `win'. It doesn't.
>
> #!/bin/ksh
> (trap 'echo win' 0)
I had a look at this, since I use ksh, and noticed the following do work:
(trap 'echo win' 0; exit)
(trap 'echo win' 0; return)
Following on that, the patch below is a possible fix. There is the comment about EXIT vs ERR, which I don't necessarily understand the implications of, so this fix might not be entirely correct, but it does appear to solve the original problem.
This problem still appears in pdksh 5.2.13, so I am cc'ing <pdksh@cs.mun.ca>.
The complete original problem report can be found via http://www.NetBSD.org/cgi-bin/query-pr-single.pl?number=6764
*** main.c.orig Sun Jan 10 13:23:38 1999
--- main.c Sun Jan 10 13:23:25 1999
***************
*** 626,632 ****
int i;
{
/* ordering for EXIT vs ERR is a bit odd (this is what at&t ksh does) */
! if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR)
&& sigtraps[SIGEXIT_].trap))
{
runtrap(&sigtraps[SIGEXIT_]);
--- 626,633 ----
int i;
{
/* ordering for EXIT vs ERR is a bit odd (this is what at&t ksh does) */
! if ((i == LEXIT || i == LLEAVE)
! || (Flag(FERREXIT) && (i == LERROR || i == LINTR)
&& sigtraps[SIGEXIT_].trap))
{
runtrap(&sigtraps[SIGEXIT_]);
From: Michael Rendell <michael@cs.mun.ca>
To: Kevin Schoedel <kevin@quipu.waterloo-rdp.on.ca>
Cc: "Charles M. Hannum" <root@ihack.net>, pdksh@cs.mun.ca,
gnats-bugs@gnats.netbsd.org, jr@cs.mun.ca
Subject: Re: bin/6764: `trap 0' does not work in ksh subshells
Date: Mon, 11 Jan 1999 17:11:24 -0330 (NST)
Hi,
On 11-Jan-99 Kevin Schoedel wrote:
>In <199901080225.VAA14271@bill-the-cat.mit.edu>, "Charles M. Hannum"
><root@ihack.net> wrote:
>>>Description:
>>
>> `trap foo 0' is supposed to execute `foo' when the shell
>> exits. This works correctly with subshells in /bin/sh but not
>> in /bin/ksh. This is a serious compatibility problem with the
>> original Korn shell.
>>
...
>I had a look at this, since I use ksh, and noticed the following do work:
>
> (trap 'echo win' 0; exit)
> (trap 'echo win' 0; return)
>
>Following on that, the patch below is a possible fix. There is the comment
>about EXIT vs ERR, which I don't necessarily understand the implications of,
>so this fix might not be entirely correct, but it does appear to solve the
>original problem.
...
>*** main.c.orig Sun Jan 10 13:23:38 1999
>--- main.c Sun Jan 10 13:23:25 1999
>***************
>*** 626,632 ****
> int i;
> {
> /* ordering for EXIT vs ERR is a bit odd (this is what at&t ksh does) */
>! if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR)
> && sigtraps[SIGEXIT_].trap))
> {
> runtrap(&sigtraps[SIGEXIT_]);
>--- 626,633 ----
> int i;
> {
> /* ordering for EXIT vs ERR is a bit odd (this is what at&t ksh does) */
>! if ((i == LEXIT || i == LLEAVE)
>! || (Flag(FERREXIT) && (i == LERROR || i == LINTR)
> && sigtraps[SIGEXIT_].trap))
> {
> runtrap(&sigtraps[SIGEXIT_]);
LLEAVE is used internally to mean `leave and don't (redo) exit traps, et al',
so this isn't a good thing to do.
Here is another fix which may work (I've done a bit of testing, but not
alot). The main thing is to do an unwind(LEXIT) when subshells exit
(used to just call exit). Some care is needed to ensure traps are only
executed in the indended process.
[These diffs will be in the next unstable release]
*** pdksh-unstable-5.2.13.6/exec.c Fri Dec 18 14:08:08 1998
--- exec.c Mon Jan 11 16:49:34 1999
***************
*** 433,439 ****
quitenv(); /* restores IO */
if ((flags&XEXEC))
! exit(rv); /* exit child */
if (rv != 0 && !(flags & XERROK)) {
if (Flag(FERREXIT))
unwind(LERROR);
--- 433,439 ----
quitenv(); /* restores IO */
if ((flags&XEXEC))
! unwind(LEXIT); /* exit child */
if (rv != 0 && !(flags & XERROK)) {
if (Flag(FERREXIT))
unwind(LERROR);
*** pdksh-unstable-5.2.13.6/sh.h Wed Dec 16 15:19:45 1998
--- sh.h Mon Jan 11 16:55:06 1999
***************
*** 539,544 ****
--- 539,545 ----
char *trap; /* trap command */
int volatile set; /* trap pending */
int flags; /* TF_* */
+ int setters_pid; /* pid of process that set trap */
handler_t cursig; /* current handler (valid if TF_ORIG_* set) */
handler_t shtrap; /* shell signal handler */
} Trap;
*** pdksh-unstable-5.2.13.6/trap.c Mon Dec 14 17:09:13 1998
--- trap.c Mon Jan 11 16:54:28 1999
***************
*** 233,243 ****
--- 233,249 ----
if (trapstr[0] == '\0') /* SIG_IGN */
return;
if (i == SIGEXIT_ || i == SIGERR_) { /* avoid recursion on these */
+ /* Only execute trap in process that requested the trap. */
+ if (procpid != p->setters_pid)
+ return;
old_changed = p->flags & TF_CHANGED;
p->flags &= ~TF_CHANGED;
p->trap = (char *) 0;
}
oexstat = exstat;
+ /* Note: trapstr is fully parsed before anything is executed, thus
+ * no problem with afree(p->trap) in settrap() while still in use.
+ */
command(trapstr);
exstat = oexstat;
if (i == SIGEXIT_ || i == SIGERR_) {
***************
*** 293,298 ****
--- 299,305 ----
p->flags |= TF_CHANGED;
f = !s ? SIG_DFL : s[0] ? trapsig : SIG_IGN;
+ p->setters_pid = procpid; /* recorded for EXIT and ERR */
p->flags |= TF_USER_SET;
if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL)
f = trapsig;
Mike
State-Changed-From-To: open->feedback
State-Changed-By: christos
State-Changed-When: Sun Apr 20 18:43:24 EDT 2003
State-Changed-Why:
another way to fix this is not to set trap = 0; in cleartraps()
State-Changed-From-To: feedback->open
State-Changed-By: tls
State-Changed-When: Wed Mar 31 04:54:07 UTC 2004
State-Changed-Why:
If we know two ways to fix this, but just aren't committing them, this bug
should not be in "feedback" state for years on end.
From: "Julio Merino" <jmmv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/6764 CVS commit: src/tests/util/sh
Date: Fri, 29 Apr 2011 12:49:36 +0000
Module Name: src
Committed By: jmmv
Date: Fri Apr 29 12:49:36 UTC 2011
Modified Files:
src/tests/util/sh: t_exit.sh
Log Message:
Add test cases for PR bin/6764: 'trap ... 0' is supposed to execute the
command when the shell exits but it does not work in ksh when the shells
exits "implicitly" (without an explicit exit/return statement).
These new tests cover both sh and ksh. The ksh part of this does not
strictly belong to this directory, but I think it'd be nice to extend
all the tests in here to cover both interpreters whenever that makes
sense, much like we do with the file system tests.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/tests/util/sh/t_exit.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/6764 CVS commit: src/bin/ksh
Date: Sun, 25 Mar 2012 13:23:49 -0400
Module Name: src
Committed By: christos
Date: Sun Mar 25 17:23:49 UTC 2012
Modified Files:
src/bin/ksh: exec.c
Log Message:
PR/6764: Charles M. Hannum: `trap 0' does not work in ksh subshells. When
subshells exit normally, use unwind(LEXIT) instead of unwind(LLEAVE) so that
traps get executed.
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/bin/ksh/exec.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Sun, 25 Mar 2012 17:44:10 +0000
State-Changed-Why:
Does christos fix solve the problem for you?
State-Changed-From-To: feedback->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sun, 06 Oct 2013 11:09:55 +0000
State-Changed-Why:
18-month feedback timeout
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.