Use ALRM/USR1 signals for timeout communikation
diff --git a/libexec/bats-core/bats-exec-test b/libexec/bats-core/bats-exec-test index e2d9cc6..a08d5f8 100755 --- a/libexec/bats-core/bats-exec-test +++ b/libexec/bats-core/bats-exec-test
@@ -116,6 +116,7 @@ local exit_metadata='' local killer_pid=${1:-} trap - ERR EXIT + trap '' ALRM # do nothing, this was for the timeout if [[ -n "${BATS_TEST_TIMEOUT:-}" ]]; then # Kill the watchdog in the case of of kernel finished before the timeout bats_strike_back "$killer_pid" || status=1 @@ -126,13 +127,12 @@ if [[ "$BATS_TEST_SKIPPED" != '1' ]]; then exit_metadata+=" $BATS_TEST_SKIPPED" fi - # 141 is the error code raised by pkill - elif [[ "$BATS_ERROR_STATUS" -eq 141 ]]; then - exit_metadata=" # timeout after $(( ($(get_mills_since_epoch) - BATS_TEST_START_TIME) / 1000 ))s" + elif [[ "${BATS_TIMED_OUT-NOTSET}" != NOTSET ]]; then + exit_metadata=" # timeout after ${BATS_TEST_TIMEOUT}s" fi BATS_TEST_TIME='' - if [[ -z "${exit_metadata}" && -n "$BATS_ENABLE_TIMING" ]]; then + if [[ -n "$BATS_ENABLE_TIMING" ]]; then BATS_TEST_TIME=" in "$(( $(get_mills_since_epoch) - BATS_TEST_START_TIME ))"ms" fi @@ -196,16 +196,27 @@ exit "$status" } +# Marks the test as failed due to timeout. +# The actual termination of subprocesses is done via pkill in the background +# process in bats_timout +bats_timeout_trap() { + BATS_TIMED_OUT=1 + BATS_DEBUG_LAST_STACK_TRACE_IS_VALID= + exit 1 +} + bats_timout() { - local target_pid - target_pid=$$ + local -ri target_pid=$$ + trap "bats_timeout_trap $target_pid" ALRM # Start another process to kill the children of this process ( - sleep "$BATS_TEST_TIMEOUT" - if kill -0 "$target_pid" &> /dev/null ; then - pkill -PIPE -P "$target_pid" &> /dev/null - wait "$target_pid" &> /dev/null - fi + sleep "$BATS_TEST_TIMEOUT" & + trap "echo USR1>&3;kill $!; exit 0" USR1 + wait + if kill -0 "$target_pid"; then + kill -ALRM "$target_pid" + pkill -P "$target_pid" + fi &> /dev/null ) & } @@ -213,7 +224,7 @@ # This will kill the killers in the case he is sleeping, local killer_pid=$1 if kill -0 "$killer_pid" &> /dev/null; then - pkill -PIPE -P "$killer_pid" &> /dev/null + pkill -USR1 -P "$killer_pid" &> /dev/null wait "$killer_pid" &> /dev/null fi wait