80 lines
2.3 KiB
Bash
Executable File
80 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
source "$ROOT_DIR/scripts/lib/process-tree.sh"
|
|
|
|
sleep 60 &
|
|
protected_pid="$!"
|
|
signal_process_snapshot "${protected_pid}|not-the-real-start-time" KILL
|
|
if ! kill -0 "$protected_pid" >/dev/null 2>&1; then
|
|
echo "FAIL: identity mismatch killed an unrelated process" >&2
|
|
exit 1
|
|
fi
|
|
kill "$protected_pid" >/dev/null 2>&1 || true
|
|
wait "$protected_pid" 2>/dev/null || true
|
|
|
|
sh -c 'sleep 60 & wait' &
|
|
parent_pid="$!"
|
|
sleep 0.1
|
|
child_pid="$(pgrep -P "$parent_pid" | head -n 1)"
|
|
|
|
if [[ -z "$child_pid" ]]; then
|
|
echo "FAIL: dummy child process was not created" >&2
|
|
stop_process_tree "$parent_pid" KILL
|
|
exit 1
|
|
fi
|
|
|
|
stop_process_tree "$parent_pid"
|
|
wait "$parent_pid" 2>/dev/null || true
|
|
sleep 0.1
|
|
|
|
child_state="$(ps -o stat= -p "$child_pid" 2>/dev/null | xargs || true)"
|
|
if [[ -n "$child_state" && "$child_state" != Z* ]]; then
|
|
echo "FAIL: child process $child_pid is still running ($child_state)" >&2
|
|
stop_process_tree "$child_pid" KILL
|
|
exit 1
|
|
fi
|
|
|
|
echo "PASS: process tree stopped"
|
|
|
|
PROCESS_TREE_TERM_WAIT_LOOPS=2
|
|
export PROCESS_TREE_TERM_WAIT_LOOPS
|
|
sh -c 'trap "" TERM; sh -c '\''trap "" TERM; sleep 60'\'' & wait' &
|
|
stubborn_parent_pid="$!"
|
|
sleep 0.1
|
|
stubborn_child_pid="$(pgrep -P "$stubborn_parent_pid" | head -n 1)"
|
|
|
|
stop_process_tree "$stubborn_parent_pid"
|
|
wait "$stubborn_parent_pid" 2>/dev/null || true
|
|
sleep 0.1
|
|
|
|
stubborn_child_state="$(ps -o stat= -p "$stubborn_child_pid" 2>/dev/null | xargs || true)"
|
|
if [[ -n "$stubborn_child_state" && "$stubborn_child_state" != Z* ]]; then
|
|
echo "FAIL: TERM-resistant child process $stubborn_child_pid is still running ($stubborn_child_state)" >&2
|
|
kill -KILL "$stubborn_child_pid" >/dev/null 2>&1 || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "PASS: TERM-resistant process tree escalated safely"
|
|
|
|
identity_marker="$(mktemp)"
|
|
rm -f "$identity_marker"
|
|
process_identity_token() {
|
|
if [[ ! -f "$identity_marker" ]]; then
|
|
touch "$identity_marker"
|
|
echo "first identity"
|
|
else
|
|
echo "reused identity"
|
|
fi
|
|
}
|
|
|
|
reused_snapshot="$(snapshot_process_tree 999999)"
|
|
rm -f "$identity_marker"
|
|
if [[ -n "$reused_snapshot" ]]; then
|
|
echo "FAIL: snapshot retained a process tree after root identity changed" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "PASS: root identity change invalidates the snapshot"
|