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