3 # Copyright © Tavian Barnes <tavianator@tavianator.com>
4 # SPDX-License-Identifier: 0BSD
10 cd "$(dirname -- "$1")"
11 echo "$PWD/$(basename -- "$1")"
15 TESTS=$(_realpath "$TESTS")
16 if [ "${BUILDDIR-}" ]; then
17 BIN=$(_realpath "$BUILDDIR/bin")
19 BIN=$(_realpath "$TESTS/../bin")
21 MKSOCK="$BIN/tests/mksock"
22 XTOUCH="$BIN/tests/xtouch"
25 # Standardize the environment
30 local SAN_OPTIONS="halt_on_error=1:log_to_syslog=0"
31 export ASAN_OPTIONS="$SAN_OPTIONS"
32 export LSAN_OPTIONS="$SAN_OPTIONS"
33 export MSAN_OPTIONS="$SAN_OPTIONS"
34 export TSAN_OPTIONS="$SAN_OPTIONS"
35 export UBSAN_OPTIONS="$SAN_OPTIONS"
40 if [ "$UNAME" = Darwin ]; then
41 # ASan on macOS likes to report
43 # malloc: nano zone abandoned due to inability to preallocate reserved vm space.
45 # to syslog, which as a side effect opens a socket which might take the
46 # place of one of the standard streams if the process is launched with
47 # it closed. This environment variable avoids the message.
48 export MallocNanoZone=0
51 # Close non-standard inherited fds
52 if [ -d /proc/self/fd ]; then
53 local fds=/proc/self/fd
58 for fd in "$fds"/*; do
59 if [ ! -e "$fd" ]; then
69 # Close stdin so bfs doesn't think we're interactive
70 # dup() the standard fds for logging even when redirected
71 exec </dev/null 3>&1 4>&2
74 # Drop root priviliges or bail
76 if command -v capsh &>/dev/null; then
77 if capsh --has-p=cap_dac_override &>/dev/null || capsh --has-p=cap_dac_read_search &>/dev/null; then
78 if [ -n "${BFS_TRIED_DROP:-}" ]; then
80 ${RED}error:${RST} Failed to drop capabilities.
87 ${YLW}warning:${RST} Running as ${BLD}$(id -un)${RST} is not recommended. Dropping ${BLD}cap_dac_override${RST} and
88 ${BLD}cap_dac_read_search${RST}.
92 BFS_TRIED_DROP=y exec capsh \
93 --drop=cap_dac_override,cap_dac_read_search \
94 --caps=cap_dac_override,cap_dac_read_search-eip \
97 elif ((EUID == 0)); then
99 if [ "$UNAME" = "Linux" ]; then
100 UNLESS=" unless ${GRN}capsh${RST} is installed"
104 ${RED}error:${RST} These tests expect filesystem permissions to be enforced, and therefore
105 will not work when run as ${BLD}$(id -un)${RST}${UNLESS}.
113 # Get the bash call stack
116 while caller $frame; do
121 # Print a message including path, line number, and command
123 local file="${1/#*\/tests\//tests\/}"
124 set -- "$file" "${@:2}"
125 color printf "${BLD}%s:%d:${RST} %s\n %s\n" "$@"
130 # Quote a command safely for eval
139 # Run a command when this (sub)shell exits
141 # Refresh trap state before trap -p
142 # See https://unix.stackexchange.com/a/556888/56202
145 # Check if the EXIT trap is already set
146 if ! trap -p EXIT | grep -q pop_defers; then
153 DEFER_CMDS+=("$(quote "$@")")
156 read -r line file < <(caller)
157 DEFER_LINES+=("$line")
158 DEFER_FILES+=("$file")
161 # Pop a single command from the defer stack and run it
163 local i=$((${#DEFER_CMDS[@]} - 1))
164 local cmd="${DEFER_CMDS[$i]}"
165 local file="${DEFER_FILES[$i]}"
166 local line="${DEFER_LINES[$i]}"
167 unset "DEFER_CMDS[$i]"
168 unset "DEFER_FILES[$i]"
169 unset "DEFER_LINES[$i]"
172 eval "$cmd" || ret=$?
174 if ((ret != 0)); then
175 debug "$file" $line "${RED}error $ret${RST}" "defer $cmd" >&4
181 # Run all deferred commands
185 while ((${#DEFER_CMDS[@]} > 0)); do