From 0f1ad3a1672bf24ee59fae05a26742fc37a5f5ae Mon Sep 17 00:00:00 2001 From: PerishCode Date: Wed, 15 Jul 2026 16:32:33 +0800 Subject: [PATCH] runtime: let the dead rest stop's goal is a pid that no longer exists - so an already-dead pid is success, not failure. The unix branch gains the exists() guards the Windows branch always had: return early when the target is gone, and accept the kill "failure" that killing the group leader already caused. This also unbreaks restart, which aborted between stop and start when the stamped vite child died with its pnpm group leader. Version steps to 0.5.3. Co-Authored-By: Claude Fable 5 --- Cargo.lock | 4 ++-- crates/cli/Cargo.toml | 2 +- crates/core/Cargo.toml | 2 +- crates/core/src/runtime/process.rs | 5 ++++- crates/core/tests/process.rs | 12 ++++++++++++ 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85a124e..6017b15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "cli" -version = "0.5.2" +version = "0.5.3" dependencies = [ "core", "serde_json", @@ -12,7 +12,7 @@ dependencies = [ [[package]] name = "core" -version = "0.5.2" +version = "0.5.3" dependencies = [ "serde", "serde_json", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index f6ec794..4df2f00 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cli" -version = "0.5.2" +version = "0.5.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index e8f5e3a..6d7be9d 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core" -version = "0.5.2" +version = "0.5.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/crates/core/src/runtime/process.rs b/crates/core/src/runtime/process.rs index e5fc566..81db9ed 100644 --- a/crates/core/src/runtime/process.rs +++ b/crates/core/src/runtime/process.rs @@ -156,6 +156,9 @@ pub fn parse(text: &str) -> Vec<(u32, String)> { pub fn stop(pid: u32) -> Result<(), String> { #[cfg(unix)] { + if !exists(pid) { + return Ok(()); + } let group = Command::new("kill") .args(["-TERM", "--", &format!("-{pid}")]) .stdout(Stdio::null()) @@ -172,7 +175,7 @@ pub fn stop(pid: u32) -> Result<(), String> { .stderr(Stdio::null()) .status() .map_err(|err| format!("kill failed: {err}"))?; - if status.success() { + if status.success() || !exists(pid) { Ok(()) } else { Err(format!( diff --git a/crates/core/tests/process.rs b/crates/core/tests/process.rs index 4caae6b..a5511b9 100644 --- a/crates/core/tests/process.rs +++ b/crates/core/tests/process.rs @@ -69,3 +69,15 @@ fn brokers() { assert_eq!(hits.len(), 1); assert_eq!(hits[0].pid, 10); } + +#[cfg(unix)] +#[test] +fn gone() { + let mut child = std::process::Command::new("sh") + .args(["-c", "exit 0"]) + .spawn() + .expect("child should spawn"); + let pid = child.id(); + child.wait().expect("child should exit"); + assert!(process::stop(pid).is_ok()); +}