Skip to content

Ensure that grandchildren cannot keep an exited child alive. - #152

Merged
ltratt merged 1 commit into
softdevteam:masterfrom
ltratt:grandchildren_cant_cause_a_stall
Sep 24, 2026
Merged

ltratt merged 1 commit into
softdevteam:masterfrom
ltratt:grandchildren_cant_cause_a_stall

Conversation

@ltratt

@ltratt ltratt commented Sep 24, 2026

Copy link
Copy Markdown
Member

snare previously only checked for a child's exit when its stderr and stdout were closed. This works fine except when the child has handed stderr's and/or stdout's file handles to grandchildren which have (for whatever reason) not exited.

The fix is conceptually simple but has annoying details: we already use SIGCHLD to inform us when a (we don't know which!) child process has died. So we now use try_wait to see if a child has exited without worrying about whether stderr/stdout have HUPed. That then means that there may be data in both file handles that we haven't read, which we need to deal with. But in the "grandchildren are alive" situation, reading from them may never reach EOF, so we only read the data that's available: fortunately, for the "normal" situation this does the right thing.

While testing this I ran into a bug in rust + OpenBSD which it turns out is fixed in rust-nightly but not in 1.98.1, so I went down that rathole, and the fix for that ends up in here. Oh well.

snare previously only checked for a child's exit when its stderr and
stdout were closed. This works fine except when the child has handed
stderr's and/or stdout's file handles to grandchildren which have (for
whatever reason) not exited.

The fix is conceptually simple but has annoying details: we already use
SIGCHLD to inform us when a (we don't know which!) child process has
died. So we now use `try_wait` to see if a child has exited without
worrying about whether stderr/stdout have `HUP`ed. That then means that
there may be data in both file handles that we haven't read, which we
need to deal with. But in the "grandchildren are alive" situation,
reading from them may never reach EOF, so we only read the data that's
available: fortunately, for the "normal" situation this does the right
thing.

While testing this I ran into a bug in rust + OpenBSD which it turns out
is fixed in rust-nightly but not in 1.98.1, so I went down that rathole,
and the fix for that ends up in here. Oh well.
@ltratt
ltratt enabled auto-merge September 24, 2026 09:25
@ltratt
ltratt added this pull request to the merge queue Sep 24, 2026
Merged via the queue into softdevteam:master with commit cdb0530 Sep 24, 2026
2 checks passed
@ltratt
ltratt deleted the grandchildren_cant_cause_a_stall branch September 24, 2026 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant