diff options
| author | andromeda <andromeda@lenovo> | 2026-01-16 21:31:03 +0100 |
|---|---|---|
| committer | andromeda <andromeda@lenovo> | 2026-01-16 21:31:03 +0100 |
| commit | eedc84d871c901992a4dae31c5a17f49f8b4a199 (patch) | |
| tree | 1bcdfb9d7f6b7fe2aa936af52feefa51e37c4446 /src | |
init
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..05fb64e --- /dev/null +++ b/src/main.rs @@ -0,0 +1,98 @@ +use nix::pty::{ForkptyResult, forkpty, PtyMaster}; +use nix::unistd::read; + +use std::vec::Vec; +use std::io::{self, Read, Write}; +use std::process::Command; +use std::thread; +use std::time::Duration; + +use vte::{Params, Parser, Perform}; + +struct Performer; +impl Perform for Performer { + fn print(&mut self, c: char) { + println!("[print] {:?}", c); + } + + fn execute(&mut self, byte: u8) { + println!("[execute] {:02x}", byte); + } + + fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { + println!( + "[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}", + params, intermediates, ignore, c + ); + } + + fn put(&mut self, byte: u8) { + println!("[put] {:02x}", byte); + } + + fn unhook(&mut self) { + println!("[unhook]"); + } + + fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { + println!("[osc_dispatch] params={:?} bell_terminated={}", params, bell_terminated); + } + + fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { + println!( + "[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}", + params, intermediates, ignore, c + ); + } + + fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { + println!( + "[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}", + intermediates, ignore, byte + ); + } +} + +fn main() { + + // TODO get rid of hard coded `sh` path + let mut pty = spawn_pty("/home/andromeda/.nix-profile/bin/sh").unwrap(); + println!("{:?}", &pty); + + let input = io::stdin(); + let mut handle = input.lock(); + + let mut statemachine = Parser::new(); + let mut performer = Performer; + let mut buf = [0u8; 2048]; + + while true { + match read(&pty, &mut buf) { + Ok(0) => break, + Ok(n) => { + statemachine.advance(&mut performer, &buf[..n]); + }, + Err(_e) => break, + }; + }; +} + +// forks a new pty and returns file descriptor of the master +fn spawn_pty(shell: &str) -> Option<PtyMaster> { + // SAFETY safe unless os out of PTYs; incredibly unlikely + match unsafe {forkpty(None, None)} { + Ok(fork_pty_res) => match fork_pty_res { + ForkptyResult::Parent {master, ..} => { + // SAFETY `master` is a valid PtyMaster + return Some(unsafe{PtyMaster::from_owned_fd(master)}); + } + ForkptyResult::Child =>{ + Command::new(shell).spawn(); + // TODO come up with an elegant solution + thread::sleep(Duration::MAX); + return None; + } + }, + Err(_e) => return None, + }; +} |
