From 57d05cb23238c93d450a871d4115abf7de9b7645 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 14 Jun 2026 16:07:49 +0300 Subject: 6m0 re-raise interrupt to $BASHPID, not $$, in render subshell The signal handler in source_template_file re-raised the caught signal with `kill -s $sig $$`. Because the function commonly runs inside backgrounded render subshells (queue_album_view_render_job), $$ expands to the main shuriken PID, not the subshell's own. On interrupt the handler therefore signalled the main shell -- which had already cleared its own staging traps -- killing it mid-cleanup (leaking the staging dir) instead of terminating just the render subshell. Re-raise to $BASHPID, the current (sub)shell's real PID, which equals $$ in the foreground case so it is correct everywhere. Extend test_template_interrupt_removes_context_file to run the render in a backgrounded subshell and assert the parent shell survives the re-raise; verified it fails against a $$-based build and passes with $BASHPID. Co-Authored-By: Claude Opus 4.8 --- src/lib/template.source.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/template.source.sh b/src/lib/template.source.sh index 152a8be..c23b870 100644 --- a/src/lib/template.source.sh +++ b/src/lib/template.source.sh @@ -332,10 +332,16 @@ source_template_file() { trap 'rm -f "$context_file"; trap - INT TERM HUP RETURN' RETURN for sig in INT TERM HUP; do # $sig is intentionally expanded now (so each handler re-raises its own - # signal); $context_file and $$ are escaped to expand when the trap runs. + # signal); $context_file and $BASHPID are escaped to expand when the trap + # runs. We re-raise to $BASHPID, not $$: source_template_file commonly + # runs in backgrounded render subshells where $$ is the main shuriken + # PID, so kill -s $sig $$ would terminate the main shell (mid-cleanup, + # after its own staging traps were cleared) instead of this subshell. + # $BASHPID is the current (sub)shell's real PID and equals $$ in the + # foreground case, so it is correct everywhere. # shellcheck disable=SC2064 trap "rm -f \"\$context_file\"; trap - INT TERM HUP RETURN; \ - kill -s $sig \$\$" "$sig" + kill -s $sig \"\$BASHPID\"" "$sig" done if { -- cgit v1.2.3