diff --git a/Cargo.lock b/Cargo.lock index ff15df3..aac95ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,12 +349,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chrono" version = "0.4.38" @@ -430,6 +424,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "command-group" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68fa787550392a9d58f44c21a3022cfb3ea3e2458b7f85d3b399d0ceeccf409" +dependencies = [ + "async-trait", + "nix", + "tokio", + "winapi", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1110,7 +1116,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -1339,13 +1345,12 @@ dependencies = [ [[package]] name = "nix" -version = "0.28.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ "bitflags 2.6.0", "cfg-if", - "cfg_aliases", "libc", ] @@ -1585,20 +1590,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "process-wrap" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ee68ae331824036479c84060534b18254c864fa73366c58d86db3b7b811619" -dependencies = [ - "futures", - "indexmap 2.2.6", - "nix", - "tokio", - "tracing", - "windows", -] - [[package]] name = "quinn" version = "0.11.2" @@ -1897,6 +1888,7 @@ dependencies = [ "async-once-cell", "async-signal", "clap", + "command-group", "console", "dashmap", "dialoguer", @@ -1909,7 +1901,6 @@ dependencies = [ "indicatif", "once_cell", "postcard", - "process-wrap", "reqwest", "reqwest-middleware", "reqwest-retry", @@ -2746,16 +2737,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" -dependencies = [ - "windows-core 0.56.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.52.0" @@ -2765,49 +2746,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-implement" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 7c3a6ed..e08a7e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,8 +55,8 @@ zip = "2.1" async-once-cell = "0.5" async-signal = "0.2" +command-group = { version = "5.0", features = ["with-tokio"] } futures = "0.3" -process-wrap = { version = "8.0", features = ["tokio1"] } reqwest = { version = "0.12", default-features = false, features = [ "rustls-tls", "http2", diff --git a/lib/system/runner.rs b/lib/system/runner.rs index 7c96991..2540df6 100644 --- a/lib/system/runner.rs +++ b/lib/system/runner.rs @@ -1,11 +1,9 @@ -#![allow(clippy::wildcard_imports)] - use std::ffi::OsStr; use std::io::Result as IoResult; use async_signal::{Signal, Signals}; +use command_group::AsyncCommandGroup; use futures::StreamExt; -use process_wrap::tokio::*; use tokio::{ process::Command, task::{spawn, JoinHandle}, @@ -71,26 +69,27 @@ where let signal_handle = spawn_signal_listener_task()?; let signal_aborter = signal_handle.abort_handle(); - // Important - we do not want to leave any zombie - // processes behind if this async function is cancelled. - // We'll use Tokio's kill on drop functionality, as well - // as wrappers for process / job groups for each platform. - let mut command = Command::new(command); - command.args(args); - let mut wrapper = TokioCommandWrap::from(command); - wrapper.wrap(KillOnDrop); + /* + Important - we do not want to leave any zombie + processes behind if this async function is cancelled. - #[cfg(windows)] - { - wrapper.wrap(JobObject); - } + Note that since we also want to spawn the child process as part + of the current process group, we have to use the builder API from + `command-group` to spawn the child process, or this won't work. - let mut child_handle = wrapper.spawn()?; + The newer `process-wrap` crate claims to also support this behavior + for inheriting process group but it doesn't seem to work as expected. + */ + let mut child_handle = Command::new(command) + .args(args) + .group() + .kill_on_drop(true) + .spawn()?; let code = tokio::select! { // If the spawned process exits cleanly, we'll return its exit code, // which may or may not exist. Interpret a non-existent code as 1. - command_result = Box::into_pin(child_handle.wait()) => { + command_result = child_handle.wait() => { let code = command_result.ok().and_then(|s| s.code()).unwrap_or(1); signal_aborter.abort(); code @@ -98,7 +97,7 @@ where // If the command was manually interrupted by a signal, we will // return a special exit code for the signal. More details above. task_result = signal_handle => { - Box::into_pin(child_handle.kill()).await.ok(); + child_handle.kill().await.ok(); task_result.unwrap_or(EXIT_CODE_GOT_SIGNAL) } };