aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts/bootstrap/buildenv.sh
diff options
context:
space:
mode:
authorGravatar Julio Merino <jmmv@google.com>2016-02-25 18:17:53 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2016-02-26 10:07:09 +0000
commit63e8d6321ae5732b552b884de69d82230cfbe1bc (patch)
treec34c87f5c39abfc4715a0979b1710cb6cbbe09e7 /scripts/bootstrap/buildenv.sh
parentb6efd0f8f287c5021d52715c47e2da23ffeb10de (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/bootstrap/buildenv.sh')
-rwxr-xr-xscripts/bootstrap/buildenv.sh58
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}