Reusable Rust crates for managing Wayland sockets and child process lifecycles.
process-manager is a Rust workspace providing two framework-agnostic crates for managing Wayland sockets and child process lifecycles. Any application that needs to spawn, track, and gracefully terminate child processes - compositors, launchers, daemons, service managers - can use these crates. They have no dependency on GTK, Smithay, or any plugin API.
process-manager-socket- Wayland socket path management (Socket,SocketBuilder,SocketManager)process-manager- Child process lifecycle management (ProcessConfig,ProcessManager, reaper thread)
Socketnewtype -PathBufwrapper withDeref<Target = Path>,Display,AsRef<OsStr>,AsRef<str>implementationsSocketBuilder- Builds socket paths inXDG_RUNTIME_DIR, validates existing names or generates unique onesSocketManager- Multi-socket manager usingDashMap, shareable viaArcacross threads- Error types -
SocketBuilderErrorandSocketManagerErrorviathiserror
ProcessConfig- Unified configuration viaTypedBuilder(command, args, env, working_dir, shell, forked, terminate_on_exit, kill_signal, restart_on_exit, stdio, socket)ProcessManager- Concurrent process tracking viaDashMap, label-based grouping, optional reaper thread- Label-based operations - Start/stop multiple processes under a shared label
- Forked/detached processes -
setsid()viapre_execfor terminal detachment - Reaper thread - Non-blocking
try_wait()polling withProcessExitEventchannel for zombie prevention and exit notifications - Signal escalation -
SIGTERMwith configurable timeout, automaticSIGKILLescalation - Wayland socket binding - Sets
WAYLAND_DISPLAYin child environment fromSocket StdioConfig- Inherit/Null/Piped enum with reader threads for output captureKillSignal-Sigterm/Sigkillenum with serde supportSignal- Broader signal enum (SIGHUP,SIGUSR1,SIGWINCH,SIGSTOP, etc.) for general process controlsend_signal/send_signal_label- Send arbitrary signals to processes without removing them from the managerrestart/restart_label- Restart processes preserving config and labelProcessInfo- Lightweight process snapshot for inspection (noChildhandle)- Serde support -
ProcessConfig,KillSignal,Signal, andSocketimplementSerialize/Deserialize - Executable resolution -
whichintegration for PATH lookup - Graceful shutdown -
terminate_on_exitflag kills processes onProcessManagerdrop
use process_manager::{ProcessConfig, ProcessManager, StdioConfig};
let manager = ProcessManager::new();
let config = ProcessConfig::builder()
.command("echo".to_string())
.args(vec!["hello world".to_string()])
.stdout(StdioConfig::Piped)
.stderr(StdioConfig::Piped)
.build();
let id = manager.start("echo-app", &config)?;
manager.stop(id)?;let config = ProcessConfig::builder()
.command("my-daemon".to_string())
.forked(true)
.terminate_on_exit(true)
.stdout(StdioConfig::Null)
.stderr(StdioConfig::Null)
.build();
let id = manager.start("daemon", &config)?;use std::time::Duration;
let (sender, receiver) = std::sync::mpsc::channel();
let manager = ProcessManager::with_reaper(Duration::from_secs(2), sender)?;
manager.start("task", &config)?;
let event = receiver.recv_timeout(Duration::from_secs(10))?;
println!("Process {} (PID {}) exited", event.label, event.pid);manager.start("worker-pool", &config)?;
manager.start("worker-pool", &config)?;
manager.start("worker-pool", &config)?;
manager.stop_label("worker-pool")?; // Stops all threeuse process_manager_socket::{SocketBuilder, SocketManager};
let socket = SocketBuilder::build(&None)?;
let config = ProcessConfig::builder()
.command("gtk4-app".to_string())
.socket(Some(socket))
.build();
let id = manager.start("wayland-client", &config)?;The main process manager. Tracks child processes in a DashMap, supports label-based grouping, and optionally runs a reaper thread.
Configuration built via TypedBuilder. Required field: command. All other fields have defaults.
Multi-socket manager using DashMap. Register, retrieve, and remove sockets by name.
Emitted by the reaper thread when a process exits. Contains id, pid, label, and restart_on_exit flag.
Broader signal enum for general process control. Supports SIGHUP, SIGUSR1, SIGUSR2, SIGWINCH, SIGSTOP, SIGCONT, SIGALRM, and more. Use send_signal() / send_signal_label() to deliver signals without stopping the process.
| Crate | Purpose |
|---|---|
dashmap |
Concurrent process/socket tracking |
nix |
Signal handling (SIGTERM, SIGKILL) |
libc |
setsid() for forked processes |
serde |
Serialization for configs, signals, and sockets |
typed-builder |
ProcessConfig builder pattern |
which |
Executable path resolution |
thiserror |
Error types |
tracing |
Logging |
MIT