Skip to content

feat: add spawn_with_child for custom ChildWrapper spawners#34

Open
domenkozar wants to merge 1 commit intowatchexec:mainfrom
domenkozar:feat/spawn-with
Open

feat: add spawn_with_child for custom ChildWrapper spawners#34
domenkozar wants to merge 1 commit intowatchexec:mainfrom
domenkozar:feat/spawn-with

Conversation

@domenkozar
Copy link
Contributor

Summary

  • Adds CommandWrap::spawn_with_child() which accepts a closure returning Box<dyn ChildWrapper> instead of a raw Child
  • pre_spawn and wrap_child hooks still run; post_spawn is skipped (requires a concrete Child)
  • Companion to feat(supervisor): SpawnFn returns Box<dyn ChildWrapper> watchexec#1033 which uses this to allow set_spawn_fn to return custom ChildWrapper implementations

Motivation

When a process is spawned by an external mechanism (e.g. a privileged cap-server for Linux capability granting), the result is not a tokio::process::Child. The existing spawn_with requires returning a concrete Child, making this impossible. spawn_with_child accepts Box<dyn ChildWrapper> directly while still running the process-wrap hook pipeline.

Test plan

  • cargo check --features tokio1 passes

🤖 Generated with Claude Code

Changes `spawn_with` so the closure returns `Box<dyn ChildWrapper>`
instead of a raw `Child`. The default `spawn()` wraps the child
before calling `spawn_with`. This enables spawning via external
mechanisms (e.g. a privileged helper) that provide their own child
lifecycle management.

The hook pipeline is: pre_spawn, spawner closure, wrap_child.
post_spawn is kept on the CommandWrapper trait but no longer called
by spawn_inner (it had zero implementations).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
domenkozar added a commit to domenkozar/watchexec that referenced this pull request Mar 14, 2026
Changes `set_spawn_fn` so the closure returns `Box<dyn ChildWrapper>`
instead of `tokio::process::Child`. The supervisor calls
`CommandWrap::spawn_with()` (updated in process-wrap to accept
`Box<dyn ChildWrapper>`) so pre_spawn and wrap_child hooks still run.

This allows callers to return custom ChildWrapper implementations
(e.g. for processes spawned via a privileged cap-server) where the
child is not a standard tokio::process::Child.

Depends on: watchexec/process-wrap#34

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
domenkozar added a commit to domenkozar/watchexec that referenced this pull request Mar 14, 2026
Changes `set_spawn_fn` so the closure returns `Box<dyn ChildWrapper>`
instead of `tokio::process::Child`. The supervisor calls
`CommandWrap::spawn_with()` (updated in process-wrap to accept
`Box<dyn ChildWrapper>`) so pre_spawn and wrap_child hooks still run.

This allows callers to return custom ChildWrapper implementations
(e.g. for processes spawned via a privileged cap-server) where the
child is not a standard tokio::process::Child.

Depends on: watchexec/process-wrap#34

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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