I'm trying to consume output from a process in Rust. If the process doesn't terminate after a certain time, I want to terminate/kill it. Ideally I'd like to wrap everything in a generator so that I can iterate the output line by line, but I'm not experienced enough for that in Rust yet.
Here's my code (src/main.rs
), using the subprocess crate:
use subprocess::{Popen, PopenConfig, Redirection};
use std::io::Read;
use std::time::Duration;
fn main() {
let mut p = Popen::create(&["bash", "-c", "echo \"Hi There!\"; sleep 1000"], PopenConfig {stdout: Redirection::Pipe, ..Default::default()}, ).unwrap();
let mut output = p.stdout.take().unwrap();
let thread = std::thread::spawn(move || {
let three_secs = Duration::from_secs(3);
let one_sec = Duration::from_secs(1);
let r = p.wait_timeout(three_secs).unwrap();
match r {
None => {
println!("Wait timed out, terminating process");
p.terminate().unwrap();
let r = p.wait_timeout(one_sec).unwrap();
match r {
None => {
println!("Termination didn't seem to work, killing");
p.kill().unwrap();
},
Some(_) => {
println!("Terminated process successfully");
},
}
p.wait().unwrap();},
Some(_) => { println!("Process returned");},
}
println!("Everything fine");
});
println!("Starting to read output");
let mut output_str = String::new();
output.read_to_string(&mut output_str).unwrap();
println!("Done reading output");
thread.join().unwrap();
println!("Output: {}", output_str);
println!("Hello, world!");
}
I'd expect the following output:
Starting to read output
Wait timed out, terminating process
Terminated process successfully
Everything fine
Done reading output
Output: Hi There!
Hello, world!
and the process finishing after three seconds. But what I get is
Starting to read output
Wait timed out, terminating process
Terminated process successfully
Everything fine
and the process doesn't terminate.
For completeness, here is my Cargo.toml
to go along with the src/main.rs
from above:
[package]
name = "subproc"
version = "0.1.0"
authors = ["<snip>"]
edition = "2018"
[dependencies]
subprocess = "0.2.4"