diff --git a/.changes/fix-before-dev-command.md b/.changes/fix-before-dev-command.md new file mode 100644 index 000000000000..d91cee75d795 --- /dev/null +++ b/.changes/fix-before-dev-command.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Properly terminate the `beforeDevCommand` process. diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index 76fc89c99ea1..b80fd3249f66 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -501,6 +501,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctrlc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf" +dependencies = [ + "nix", + "winapi 0.3.9", +] + [[package]] name = "darling" version = "0.13.1" @@ -1546,6 +1556,19 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -2707,6 +2730,7 @@ dependencies = [ "base64", "clap", "colored", + "ctrlc", "dialoguer", "encode_unicode", "glob", diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml index 06f0908bcd6e..f6285af6ca4b 100644 --- a/tooling/cli/Cargo.toml +++ b/tooling/cli/Cargo.toml @@ -62,6 +62,7 @@ dialoguer = "0.10" url = { version = "2.2", features = [ "serde" ] } os_pipe = "1" ignore = "0.4" +ctrlc = "3.2" [target."cfg(windows)".dependencies] encode_unicode = "0.3" diff --git a/tooling/cli/src/dev.rs b/tooling/cli/src/dev.rs index 587cd0b6bfb6..78ce65edae1b 100644 --- a/tooling/cli/src/dev.rs +++ b/tooling/cli/src/dev.rs @@ -24,6 +24,7 @@ use std::{ ffi::OsStr, process::{exit, Command}, sync::{ + atomic::{AtomicBool, Ordering}, mpsc::{channel, Receiver}, Arc, Mutex, }, @@ -31,6 +32,7 @@ use std::{ }; static BEFORE_DEV: OnceCell>> = OnceCell::new(); +static KILL_BEFORE_DEV_FLAG: OnceCell = OnceCell::new(); #[derive(Debug, Parser)] #[clap(about = "Tauri dev", trailing_var_arg(true))] @@ -116,13 +118,19 @@ pub fn command(options: Options) -> Result<()> { let status = child_ .wait() .expect("failed to wait on \"beforeDevCommand\""); - if !status.success() { + if !(status.success() || KILL_BEFORE_DEV_FLAG.get().unwrap().load(Ordering::Relaxed)) { logger_.error("The \"beforeDevCommand\" terminated with a non-zero status code."); exit(status.code().unwrap_or(1)); } }); BEFORE_DEV.set(Mutex::new(child)).unwrap(); + KILL_BEFORE_DEV_FLAG.set(AtomicBool::default()).unwrap(); + + let _ = ctrlc::set_handler(move || { + kill_before_dev_process(); + exit(130); + }); } } @@ -280,11 +288,15 @@ pub fn command(options: Options) -> Result<()> { fn kill_before_dev_process() { if let Some(child) = BEFORE_DEV.get() { let child = child.lock().unwrap(); + KILL_BEFORE_DEV_FLAG + .get() + .unwrap() + .store(true, Ordering::Relaxed); #[cfg(windows)] let _ = Command::new("powershell") .arg("-NoProfile") .arg("-Command") - .arg(format!("function Kill-Tree {{ Param([int]$ppid); Get-CimInstance Win32_Process | Where-Object {{ $_.ParentProcessId -eq $ppid }} | ForEach-Object {{ Kill-Tree $_.ProcessId }}; Stop-Process -Id $ppid }}; Kill-Tree {}", child.id())) + .arg(format!("function Kill-Tree {{ Param([int]$ppid); Get-CimInstance Win32_Process | Where-Object {{ $_.ParentProcessId -eq $ppid }} | ForEach-Object {{ Kill-Tree $_.ProcessId }}; Stop-Process -Id $ppid -ErrorAction SilentlyContinue }}; Kill-Tree {}", child.id())) .status(); #[cfg(not(windows))] let _ = Command::new("pkill")