From ed5cea5f7383b720604141b7384ed6ef9390b088 Mon Sep 17 00:00:00 2001 From: Robin Stocker Date: Fri, 1 Jul 2016 14:31:36 +1000 Subject: [PATCH] Use CommandExt::exec for `cargo run` on Unix (#2343) Before, we would spawn a child process for the program. One of the problems with that is when killing the cargo process, the program continues running. With this change, the cargo process is replaced by the program, and killing it works. --- src/cargo/ops/cargo_run.rs | 2 +- src/cargo/util/process_builder.rs | 16 ++++++++++++++++ tests/run.rs | 25 +++++++++++++++++-------- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 34c28dbc4cb..897a3da5116 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -52,5 +52,5 @@ pub fn run(ws: &Workspace, process.args(args).cwd(config.cwd()); try!(config.shell().status("Running", process.to_string())); - Ok(process.exec().err()) + Ok(process.exec_replace().err()) } diff --git a/src/cargo/util/process_builder.rs b/src/cargo/util/process_builder.rs index c0d88d2ae86..b66b26ec0a4 100644 --- a/src/cargo/util/process_builder.rs +++ b/src/cargo/util/process_builder.rs @@ -89,6 +89,22 @@ impl ProcessBuilder { } } + #[cfg(unix)] + pub fn exec_replace(&self) -> Result<(), ProcessError> { + use std::os::unix::process::CommandExt; + + let mut command = self.build_command(); + let error = command.exec(); + Err(process_error(&format!("could not execute process `{}`", + self.debug_string()), + Some(Box::new(error)), None, None)) + } + + #[cfg(windows)] + pub fn exec_replace(&self) -> Result<(), ProcessError> { + self.exec() + } + pub fn exec_with_output(&self) -> Result { let mut command = self.build_command(); diff --git a/tests/run.rs b/tests/run.rs index 7c769c24515..eb438ac4170 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -126,14 +126,18 @@ fn exit_code() { fn main() { std::process::exit(2); } "#); - assert_that(p.cargo_process("run"), - execs().with_status(2) - .with_stderr("\ + let mut output = String::from("\ [COMPILING] foo v0.0.1 (file[..]) [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target[..]` +"); + if !cfg!(unix) { + output.push_str("\ [ERROR] process didn't exit successfully: `target[..]foo[..]` (exit code: 2) -")); +"); + } + assert_that(p.cargo_process("run"), + execs().with_status(2).with_stderr(output)); } #[test] @@ -149,15 +153,20 @@ fn exit_code_verbose() { fn main() { std::process::exit(2); } "#); - assert_that(p.cargo_process("run").arg("-v"), - execs().with_status(2) - .with_stderr("\ + let mut output = String::from("\ [COMPILING] foo v0.0.1 (file[..]) [RUNNING] `rustc [..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target[..]` +"); + if !cfg!(unix) { + output.push_str("\ [ERROR] process didn't exit successfully: `target[..]foo[..]` (exit code: 2) -")); +"); + } + + assert_that(p.cargo_process("run").arg("-v"), + execs().with_status(2).with_stderr(output)); } #[test]