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

Reply via email to