You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
distant/src/cli/commands/client/stdin.rs

37 lines
1.2 KiB
Rust

use log::error;
use std::{
io::{self, BufReader, Read},
thread,
};
use tokio::sync::mpsc;
/// Creates a new thread that performs stdin reads in a blocking fashion, returning
/// a handle to the thread and a receiver that will be sent input as it becomes available
pub fn spawn_channel(buffer: usize) -> (thread::JoinHandle<()>, mpsc::Receiver<Vec<u8>>) {
let (tx, rx) = mpsc::channel(1);
// NOTE: Using blocking I/O per tokio's advice to read from stdin line-by-line and then
// pass the results to a separate async handler to forward to the remote process
let handle = thread::spawn(move || {
let mut stdin = BufReader::new(io::stdin());
// Maximum chunk that we expect to read at any one time
let mut buf = vec![0; buffer];
loop {
match stdin.read(&mut buf) {
Ok(0) | Err(_) => break,
Ok(n) => {
if let Err(x) = tx.blocking_send(buf[..n].to_vec()) {
error!("Stdin channel closed: {}", x);
break;
}
thread::yield_now();
}
}
}
});
(handle, rx)
}