pdksh (though not recent versions of
mksh derived from that),
yash, the Bourne shell behave like
mksh behave otherwise.
The POSIX spec is not clear on what should be the correct behaviour, but there's nothing in there that says that the shell is allowed to override the default handler for the SIGINT (or other) signal.
It says the EXIT trap action should be evaluated when
exit is invoked, but AFAICT, it doesn't even say for instance if it should be evaluated when the shell exits as the result of
set -e or
set -u or error conditions like syntax errors or failing special builtins.
To be able to run the EXIT trap upon reception of a signal, the shell would need to install a handler on that signal.
bash do, but the list of signals they handle is different between all three implementations. The only signals common between all 3 seem to be INT, QUIT, TERM, ALRM and HUP.
If you want the EXIT trap to be run upon some signals, the portable way would be to handle those signals yourself:
trap 'exit 1' INT HUP QUIT TERM ALRM USR1
trap 'cleanup' EXIT
That approach however doesn't work with
zsh, which doesn't run the EXIT trap if
exit is called from a trap handler.
It also fails to report your death-by-signal to your parent.
So instead, you could do:
for sig in INT QUIT HUP TERM ALRM USR1; do
trap - $sig EXIT
kill -s $sig "'"$$"' "$sig"
trap cleanup EXIT
Now, beware though that if more signals arrive while you're executing
cleanup may be run again. You may want to make sure your
cleanup works correctly if invoked several times and/or ignore signals during its execution.