Expand description
Containment::Sanitized — spawn a child with no orphaned inheritable
handles from the parent’s table. Only the stdio handles we explicitly
create (NUL on every platform) are passed into the child.
Motivation: when a process tree has a pipe-redirected ancestor (e.g. a
Python subprocess.Popen(stdout=PIPE) several levels up), every
intermediate CreateProcessW(bInheritHandles=TRUE) on Windows — and every
fork+exec of an fd without FD_CLOEXEC on Unix — duplicates that
orphaned pipe write-end into the new child. If a daemon ends up at the
bottom of that chain, the original reader at the top never sees EOF.
Sanitized spawn fixes this by:
-
Windows: opening NUL three times for stdin/stdout/stderr, then calling
CreateProcessWwithSTARTUPINFOEX+PROC_THREAD_ATTRIBUTE_HANDLE_LISTcontaining only those three handles. The kernel ignores the “all inheritable handles” rule and duplicates exactly the listed handles into the child. Any orphaned ancestor pipe stays in the parent. -
Unix: spawning with
Stdio::null()for the three stdio slots (which Rust marksO_CLOEXECinternally), and apre_execclosure that walks/dev/fd(or/proc/self/fd) in the forked child and closes every fd > 2 beforeexec. Equivalent to what nginx, sshd, and other production daemons do.
Issue: https://github.com/zackees/running-process/issues/110.
Structs§
- Sanitized
Child - A child spawned via
ContainedProcessGroup::spawn_sanitized.
Functions§
- spawn
- Spawn
commandwith sanitized handle inheritance. See the module docs for the cross-platform behavior.