fmt, use waitpid to exit

This commit is contained in:
andromeda
2026-01-18 12:47:12 +01:00
parent aecca6f229
commit d2ed0e974b

View File

@@ -1,6 +1,7 @@
use nix::fcntl::{fcntl, OFlag, F_GETFL, F_SETFL};
use nix::pty::{forkpty, ForkptyResult, PtyMaster};
use nix::unistd::{execve, read, write};
use nix::fcntl::{F_GETFL, F_SETFL, OFlag, fcntl};
use nix::pty::{ForkptyResult, PtyMaster, forkpty};
use nix::sys::wait::{WaitPidFlag, WaitStatus, waitpid};
use nix::unistd::{Pid, execve, read, write};
use minifb::{Key, KeyRepeat, Window, WindowOptions};
@@ -79,13 +80,13 @@ impl Perform for Model {
for row in 0..(self.buffer.height - 1) {
for col in 0..self.buffer.width {
self.buffer.set(col, row, self.buffer.get(col, row + 1));
};
};
}
}
for col in 0..self.buffer.width {
self.buffer.set(col, self.buffer.height - 1, None);
}
self.cursor.row -= 1;
};
}
self.buffer.set(self.cursor.col, self.cursor.row, Some(c));
self.cursor.col += 1;
}
@@ -100,7 +101,7 @@ impl Perform for Model {
0x08 => {
self.cursor.col = self.cursor.col - 1;
self.buffer.set(self.cursor.col, self.cursor.row, None);
},
}
_ => (),
}
println!("[execute] {:02x}", byte);
@@ -193,7 +194,7 @@ fn main() {
// initialize window and its buffer
let mut window = Window::new(
"rust-term",
"rustty",
model.screenbuffer.width,
model.screenbuffer.height,
WindowOptions::default(),
@@ -201,7 +202,7 @@ fn main() {
.unwrap();
window.set_target_fps(60);
let pty = spawn_pty().unwrap();
let (pty, child) = spawn_pty().unwrap();
fcntl(
&pty,
F_SETFL(OFlag::from_bits_truncate(fcntl(&pty, F_GETFL).unwrap()) | OFlag::O_NONBLOCK),
@@ -211,7 +212,10 @@ fn main() {
let mut statemachine = Parser::new();
let mut buf = [0u8; 2048];
while window.is_open() && !window.is_key_down(Key::Escape) {
while window.is_open()
&& !window.is_key_down(Key::Escape)
&& waitpid(child, Some(WaitPidFlag::WNOHANG)) == Ok(WaitStatus::StillAlive)
{
// mask to render into
let mut mask = vec![0u8; model.screenbuffer.width * model.screenbuffer.height];
@@ -260,17 +264,20 @@ fn main() {
};
let keys = window.get_keys_pressed(KeyRepeat::Yes);
let shift = window.is_key_down(Key::LeftShift) || window.is_key_down(Key::RightShift) || window.is_key_down(Key::CapsLock);
let shift = window.is_key_down(Key::LeftShift)
|| window.is_key_down(Key::RightShift)
|| window.is_key_down(Key::CapsLock);
let ctrl = window.is_key_down(Key::LeftCtrl) || window.is_key_down(Key::RightCtrl);
if !keys.is_empty() {
let bytes: Vec<u8> = keys
.iter()
// TODO apply modifiers
.map(|key| key_to_u8(
.map(|key| {
key_to_u8(
*key, // key
shift,
ctrl
))
shift, ctrl,
)
})
.filter(|v| *v != 0u8)
.collect();
write(&pty, bytes.as_slice());
@@ -279,23 +286,25 @@ fn main() {
}
// forks a new pty and returns file descriptor of the master
fn spawn_pty() -> Option<PtyMaster> {
fn spawn_pty() -> Option<(PtyMaster, Pid)> {
// SAFETY safe unless os out of PTYs; incredibly unlikely
match unsafe { forkpty(None, None) } {
Ok(fork_pty_res) => match fork_pty_res {
ForkptyResult::Parent { child: _, master } => {
ForkptyResult::Parent { child, master } => {
// SAFETY `master` is a valid PtyMaster
return Some(unsafe { PtyMaster::from_owned_fd(master) });
return Some((unsafe { PtyMaster::from_owned_fd(master) }, child));
}
ForkptyResult::Child => {
let _ = execve::<CString, CString>(
&CString::new("/usr/bin/env").unwrap(),
&[ CString::new("/usr/bin/env").unwrap(),
&[
CString::new("/usr/bin/env").unwrap(),
CString::new("-i").unwrap(),
CString::new("sh").unwrap(),
CString::new("--norc").unwrap(),
CString::new("--noprofile").unwrap() ],
&[ CString::new("TERM=dumb").unwrap() ],
CString::new("--noprofile").unwrap(),
],
&[CString::new("TERM=dumb").unwrap()],
);
return None;
}