Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing stdout or stdin

Tags:

rust

Since files and streams are closed automatically when being dropped, but io::stdin() only providing a handle to the underlying stream, I fail to see how to explicitly close stdin or stdout or detect EOF on stdin in my program.

Consider

fn main() {
    let mut stdin = io::stdin();
    let mut linebuffer = String::new();
    loop {
        match stdin.read_line(&mut linebuffer) {
            Ok(i) if i == 0 => { break; },
            Ok(i) => {
                println!("{} {}", linebuffer, i);
            },
            Err(e) => { panic!(e); }
        }
        linebuffer.clear();
    }
}

Checking the number of bytes put into the buffer seems flaky because the pipe might get flushed with zero bytes having being written to it. Reading from a closed stdin should cause an IOError, but it doesn't.

Somewhat related to that: How to explicitly close my own stdout / stderr?

like image 253
user2722968 Avatar asked Jun 11 '15 09:06

user2722968


2 Answers

Some time ago there was ErrorKind::EndOfFile enum variant which was emitted upon a read operation when the source stream is closed. It seems that it didn't get to the new I/O library implementation, and instead Read trait has been changed to return 0 read bytes upon EOF. And indeed, this is specified in I/O reform RFC. So yes, checking for zero is a valid way to detect end of stream in the current Rust.

By the way, you can write Ok(0) instead of Ok(i) if i == 0:

match stdin.read_line(&mut buf) {
    Ok(0) => break,
    ...
}

As for how to close stdout()/stderr(), it seems that the current API does not provide a way to do it, unfortunately. It is probably a feature worth an RFC or at least an RFC issue.

like image 173
Vladimir Matveev Avatar answered Oct 15 '22 10:10

Vladimir Matveev


Regarding my own sub-question on how to close stdout/stderr: The correct way is to use the wait- or the wait_with_output-method on a process::Child. Both methods close the subprocess's stdin before waiting for it to quit, eliminating the possibility of a deadlock between both processes.

like image 38
user2722968 Avatar answered Oct 15 '22 10:10

user2722968