diff options
author | Julio Merino <jmmv@google.com> | 2016-02-25 18:17:53 +0000 |
---|---|---|
committer | Philipp Wollermann <philwo@google.com> | 2016-02-26 10:07:09 +0000 |
commit | 63e8d6321ae5732b552b884de69d82230cfbe1bc (patch) | |
tree | c34c87f5c39abfc4715a0979b1710cb6cbbe09e7 /scripts | |
parent | b6efd0f8f287c5021d52715c47e2da23ffeb10de (diff) |
Improve handling of exit routines to ensure we respect the exit status.
As part of this, change atexit to receive the name of a function instead of
just a chunk of code. This way, we can also control the return value of
each individual atexit function and report it to the user, should these
routines fail when the program apparently succeeded.
--
MOS_MIGRATED_REVID=115575895
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/bootstrap/buildenv.sh | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/scripts/bootstrap/buildenv.sh b/scripts/bootstrap/buildenv.sh index 63d0897ba7..fa692046ee 100755 --- a/scripts/bootstrap/buildenv.sh +++ b/scripts/bootstrap/buildenv.sh @@ -43,25 +43,71 @@ msys*|mingw*) EXE_EXT=".exe" esac -ATEXIT_="" +# List of functions to invoke on exit. +ATEXIT_HANDLERS= + +# Registers a function to be invoked on exit. +# +# The handlers will be invoked at exit time in the order they were registered. +# See comments in run_atexit for more details. function atexit() { - ATEXIT_="$1; ${ATEXIT_}" - trap "{ ${ATEXIT_} }" EXIT + local handler="${1}"; shift + + [ -n "${ATEXIT_HANDLERS}" ] || trap 'run_atexit_handlers $?' EXIT + ATEXIT_HANDLERS="${ATEXIT_HANDLERS} ${handler}" +} + +# Exit routine to run all registered atexit handlers. +# +# If the program exited with an error, this exit routine will also exit with the +# same error. However, if the program exited successfully, this exit routine +# will only exit successfully if the atexit handlers succeed. +function run_atexit_handlers() { + local exit_code="$?" + + local failed=no + for handler in ${ATEXIT_HANDLERS}; do + eval "${handler}" || failed=yes + done + + trap - EXIT # Reset exit handler to prevent double execution. + if [ ${exit_code} -ne 0 ]; then + exit ${exit_code} + else + if [ "${failed}" = yes ]; then + echo "Program tried to exit successfully but atexit routines failed" 1>&2 + exit 1 + else + exit 0 + fi + fi } function tempdir() { local tmp=${TMPDIR:-/tmp} local DIR="$(mktemp -d ${tmp%%/}/bazel.XXXXXXXX)" mkdir -p "${DIR}" - atexit "rm -fr ${DIR}" + eval "cleanup_tempdir() { rm -rf '${DIR}'; }" + atexit cleanup_tempdir NEW_TMPDIR="${DIR}" } tempdir OUTPUT_DIR=${NEW_TMPDIR} errfile=${OUTPUT_DIR}/errors -atexit "if [ -f ${errfile} ]; then cat ${errfile} >&2; fi" +eval "cleanup_errfile() { + if [ -f '${errfile}' ]; then + cat '${errfile}' 1>&2; + fi; + }" +atexit cleanup_errfile phasefile=${OUTPUT_DIR}/phase -atexit "if [ -f ${phasefile} ]; then echo >&2; cat ${phasefile} >&2; fi" +eval "cleanup_phasefile() { + if [ -f '${phasefile}' ]; then + echo 1>&2; + cat '${phasefile}' 1>&2; + fi; + }" +atexit cleanup_phasefile function run_silent() { echo "${@}" >${errfile} |