mirror of https://github.com/chipsenkbeil/distant
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.
37 lines
1.2 KiB
Rust
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)
|
|
}
|