This works for me (improved thanks to the commenters):
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
kill -- -$$
sends a SIGTERM to the whole process group, thus killing also descendants.
Specifying signal EXIT
is useful when using set -e
(more details here).