extern crate pseudoterm;
use pseudoterm::{OpenptyOptions, RawTerminal, Winsize};
use std::{
env,
io::{self, prelude::*},
process::Command,
thread
};
fn main() -> io::Result<()> {
let mut args = env::args().skip(1);
let cmd = match args.next() {
Some(cmd) => cmd,
None => {
eprintln!("Usage: pty <cmd>");
return Ok(());
}
};
let (mut master, slave) = pseudoterm::openpty(
&OpenptyOptions::new()
.with_size(Winsize {
cols: 80,
rows: 32,
})
)?;
let mut child = pseudoterm::prepare_cmd(slave, &mut Command::new(cmd))?
.args(args)
.spawn()?;
let mut clone = master.try_clone()?;
thread::spawn(move || {
let stdin = io::stdin();
let mut stdin = stdin.lock();
let mut buf = [0; 1024];
loop {
let res = match stdin.read(&mut buf) {
Ok(0) => break,
Ok(n) => clone.write_all(&buf[..n]),
Err(err) => Err(err)
};
if let Err(err) = res {
eprintln!("{}", err);
return;
}
}
});
let stdout = io::stdout();
let mut stdout = RawTerminal::new_allow_failure(stdout);
let mut buf = [0; 1024];
loop {
match master.read(&mut buf) {
Ok(0) | Err(_) => break,
Ok(n) => {
stdout.write_all(&buf[..n])?;
stdout.flush()?;
}
}
}
child.wait()?;
Ok(())
}