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