The ERR trap is supposed to be run once, regardless of errexit:
$ ksh -c 'trap "echo ERR" ERR; false'
ERR
$ ksh -c 'trap "echo ERR" ERR; false' -e
ERR
ERR
This duplication is a regression of the following bin/ksh/main.c commit:
revision 1.52
date: 2013/06/15 17:25:19; author: millert; state: Exp; lines: +5 -1;
Run any pending traps before calling the EXIT or ERR traps when -e
is set. Fixes a bug where we would not run the signal trap if,
for example, ^C was pressed and -e was set. OK espie@
Revert it and add a new test, matching bash(1) behaviour:
$ ./obj/ksh -c 'trap "echo ERR" ERR; false'
ERR
$ ./obj/ksh -c 'trap "echo ERR" ERR; false' -e
ERR
After that, fix signal handlers (e.g. SIGINT/^C traps) properly.
Feedback? Objection? OK?
Index: bin/ksh/main.c
===================================================================
RCS file: /cvs/src/bin/ksh/main.c,v
retrieving revision 1.98
diff -u -p -r1.98 main.c
--- bin/ksh/main.c 28 Jun 2019 13:34:59 -0000 1.98
+++ bin/ksh/main.c 10 Oct 2022 19:23:58 -0000
@@ -652,13 +652,9 @@ unwind(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)) {
- if (trap)
- runtraps(0);
runtrap(&sigtraps[SIGEXIT_]);
i = LLEAVE;
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
- if (trap)
- runtraps(0);
runtrap(&sigtraps[SIGERR_]);
i = LLEAVE;
}
Index: regress/bin/ksh/trap.t
===================================================================
RCS file: /cvs/src/regress/bin/ksh/trap.t,v
retrieving revision 1.1
diff -u -p -r1.1 trap.t
--- regress/bin/ksh/trap.t 10 Oct 2022 14:57:48 -0000 1.1
+++ regress/bin/ksh/trap.t 10 Oct 2022 20:47:33 -0000
@@ -47,3 +47,16 @@ expected-stderr-pattern:
/Is a directory/
expected-exit: e != 0
---
+
+
+name: errexit-triggers-ERR-once
+description:
+ Check that the errexit option does not trigger the ERR trap more than
once.
+arguments: !-e!
+stdin:
+ trap 'echo ERR' ERR
+ false
+expected-stdout:
+ ERR
+expected-exit: e != 0
+---