On Tue, 10 Jul 2007, Clint Pachl wrote: > I wanted to know if others thought pdksh v5.2.14's behavior is incorrect when > trapping the EXIT and ERR. I wrote four tests to demonstrate. TEST_1 fails in > my opinion. I believe it should output the following: > ERR > EXIT > > > # TEST_1 > trap 'echo EXIT' EXIT > trap 'echo ERR' ERR > set -e > cd /XXXXX 2>/dev/null > echo DONE > exit 0 > =====OUTPUT=====(BAD) > EXIT > > > # TEST_2 > trap 'echo EXIT' EXIT > trap 'echo ERR' ERR > #set -e > cd /XXXXX 2>/dev/null > echo DONE > exit 0 > =====OUTPUT=====(GOOD) > ERR > DONE > EXIT > > > # TEST_3 > #trap 'echo EXIT' EXIT > trap 'echo ERR' ERR > set -e > cd /XXXXX 2>/dev/null > echo DONE > exit 0 > =====OUTPUT=====(GOOD) > ERR > > > # TEST_4 > trap 'echo EXIT' EXIT > #trap 'echo ERR' ERR > set -e > cd /XXXXX 2>/dev/null > echo DONE > exit 0 > =====OUTPUT=====(GOOD) > EXIT > > > I also tried the tests in at&t ksh93. For TEST_[234], the output is the same > as above. For TEST_1, it "correctly" outputs: > ERR > EXIT > > > After a quick grep through /usr/src/bin/ksh for EXIT and ERR I made a quick > change to main.c. I also found the comment interesting. > > --- main.c Tue Jul 10 18:43:22 2007 > +++ /usr/src/bin/ksh/main.c Tue May 15 18:56:46 2007 > @@ -582,12 +582,12 @@ > unwind(int i) > { > /* ordering for EXIT vs ERR is a bit odd (this is what at&t ksh does) > */ > - if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) { > - runtrap(&sigtraps[SIGERR_]); > - i = LLEAVE; > - } else if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == > LINTR) && > + if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR) && > sigtraps[SIGEXIT_].trap)) { > runtrap(&sigtraps[SIGEXIT_]); > + i = LLEAVE; > + } else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) { > + runtrap(&sigtraps[SIGERR_]); > i = LLEAVE; > } > while (1) { > > > After applying the patch above, TEST_1 outputs "ERR" instead of "EXIT." This > seems closer, just need to comeback and run the EXIT trap. If people think > this is a bug I will investigate further. > > Also, according to OBSD's ksh(1) man page, TEST_1 hints at a possible bug. > > set command > ... > -e | errexit Exit (after executing the ERR trap) as soon as > an error occurs or a command fails (i.e. exits > with a non-zero status). This does not apply to > commands whose exit status is explicitly tested > by a shell construct such as if, until, while, > &&, or || statements. > > -pachl > >
Yes, there are bugs wrt to ERR and EXIT traps. I have this diff in my tree, which solves the case below (ERR handler is not called) and your first test case. Will look into your diff later. Test case originally by grunk@ -Otto Index: exec.c =================================================================== RCS file: /cvs/src/bin/ksh/exec.c,v retrieving revision 1.46 diff -u -p -r1.46 exec.c --- exec.c 10 Apr 2006 14:38:59 -0000 1.46 +++ exec.c 11 Jul 2007 05:55:17 -0000 @@ -363,9 +363,9 @@ execute(struct op *volatile t, if ((flags&XEXEC)) unwind(LEXIT); /* exit child */ if (rv != 0 && !(flags & XERROK)) { + trapsig(SIGERR_); if (Flag(FERREXIT)) unwind(LERROR); - trapsig(SIGERR_); } return rv; } #!/bin/sh set -e handler() { echo "INT" } errhandler() { echo "ERR" } exithandler() { echo "EXIT" } # Bug: leaving out one of the signals causes no output on ^C trap handler INT trap exithandler EXIT trap errhandler ERR trap handler HUP trap cat <<EOF Interrupt me with ^C to see what happens. Waiting 600s now... EOF sleep 600 echo "Finished."