How can I read non-blocking from stdin?
Is there a way to check if data is available stdin
in Rust, or to perform a read that returns immediately with the currently available data?
My goal is to read the input generated by, for example, the cursor keys in a shell that is configured to return all read data immediately. For example, with the equivalent of: stty -echo -echok -icanon min 1 time 0
.
I suppose one solution would be to use ncurses or similar libraries, but I would like to avoid any big dependencies.
So far, I've only gotten input locking, which is what I don't want:
let mut reader = stdin();
let mut s = String::new();
match reader.read_to_string(&mut s) {...} // this blocks :(
source to share
Most operating systems work with standard input and output in a blocked way by default. Unsurprisingly, the Rust library appears instead.
To read from a blocking thread in a non-blocking way, you can create a separate thread to allow additional blocks of threads instead of the main one. Checking that the blocking file descriptor has produced some input is similar: create a stream, force it to read data, check if it has produced any data so far.
Here is a code snippet that I am using for a similar purpose of handling the output of a pipe interactively and hopefully can serve as an example. It sends data through a channel that supports try_recv - allows you to check if data is available or not.
Someone told me that mio can use to read from a pipe in a non-blocking way, so you might want to test it as well. I suspect passing the stdin (0) file descriptor to PipeReader :: from_fd should work.
source to share