build_all: clean Ctrl+C in parallel mode (kill job trees on INT/TERM)

Trap INT/TERM around the parallel wait recursively kills each job's process
tree (subshell + grandchildren: podman container, flatpak-builder, pyinstaller),
then exits 130 — the EXIT trap frees the tmpfs scratch. Verified: SIGINT leaves
no orphan processes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 10:46:11 +02:00
parent 46583f5622
commit f748dae369

View File

@@ -112,6 +112,29 @@ step() {
echo "================================================================"
}
# Kill a process and its whole descendant tree (children first) — used by the
# interrupt handler so SIGINT also stops grandchildren the parallel jobs spawned
# (podman container, flatpak-builder, pyinstaller …), not just the subshells.
_kill_tree() {
local pid=$1 c
for c in $(pgrep -P "$pid" 2>/dev/null); do
_kill_tree "$c"
done
kill -TERM "$pid" 2>/dev/null || true
}
# Set as INT/TERM handler around the parallel wait. Stops every running build
# tree, then exits — the EXIT trap (set under --ram) frees the tmpfs scratch.
_interrupt() {
echo >&2
echo "-- interrupted: stopping running builds…" >&2
local pid
for pid in "${!PID2NAME[@]}"; do
_kill_tree "$pid"
done
exit 130
}
# ---------- artifact paths ----------------------------------------------------
MANUAL="$DIST_DIR/testium-manual-${VERSION}.pdf"
@@ -229,6 +252,9 @@ else
PID2NAME[$!]="$name"
done
# From here until all jobs are reaped, Ctrl+C stops every build tree.
trap _interrupt INT TERM
FAILED=()
for pid in "${!PID2NAME[@]}"; do
name="${PID2NAME[$pid]}"
@@ -240,6 +266,8 @@ else
fi
done
trap - INT TERM
if [ "${#FAILED[@]}" -gt 0 ]; then
for name in "${FAILED[@]}"; do
echo