1
votes

This question refers to Rust as of October 2014.

If you are using Rust 1.0 or above, you best look elsewhere for a solution.


I have a long running Rust process that generates log values, which I'm running using Process.

It looks at though I might be able to periodically "check on" the running process using set_timeout() and wait() and do something kind of high level loop like:

let mut child = match Command::new("thing").arg("...").spawn() {
    Ok(child) => child,
    Err(e) => fail!("failed to execute child: {}", e),
};
loop {
    child.set_timeout(Some(100));
    match child.wait() {
        // ??? Something goes here
    }
}

The things I'm not 100% on are; how do I tell the difference between a timeout error and a process-return error from wait(), and how to a use the PipeStream to "read as much as you can without blocking from the stream" every interval to push out.

Is this the best approach? Should I start a task to monitor stdout and stderr instead?

1
The edit you made was too drastic - it invalidated the existing answer. I've rolled back the edit and refunded your bounty. Please ask a new question. If you don't want this question on the site you can delete it as it only has one answer without any upvotes. - ChrisF♦
No, I am not kidding. The edit was a complete rewrite of the question. It would have been better to ask a completely new question. - ChrisF♦
@Doug: your question together with the answers is a shared work. You rewriting the question invalidates and vandalises that work. - Martijn Pieters♦
@Doug: while I can appreciate that Rust only reached 1.0 in May 2015, there is always a possibility that someone runs an older release where your question and the answer below were still applicable. You don't just get to decide that someone else's work on this question can be summarily invalidated. - Martijn Pieters♦
@Doug, re: "What qualifies you to make that arbitrary decision?" -- people with diamonds by their names have been elected to make such decisions on behalf of the community. - Charles Duffy

1 Answers

5
votes

For distinguishing the errors from the process from the timeout, you have to manage the returns from wait, an example here:

fn run() {
    let mut child = match Command::new("sleep").arg("1").spawn() {
        Ok(child) => child,
        Err(e) => fail!("failed to execute child: {}", e),
    };
    loop {
        child.set_timeout(Some(1000));
        match child.wait() {
            // Here assume any error is timeout, you can filter from IoErrorKind
            Err(..) => println!("Timeout"),
            Ok(ExitStatus(0)) => {
                println!("Finished without errors");
                return;
            }
            Ok(ExitStatus(a)) => {
                println!("Finished with error number: {}", a);
                return;
            }
            Ok(ExitSignal(a)) => {
                println!("Terminated by signal number: {}", a);
                return;
            }
        }
    }
}

About using streams, check with wait_with_output, or implement something similar with channels and threads : http://doc.rust-lang.org/src/std/home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libstd/io/process.rs.html#601

Hope it helped