summaryrefslogtreecommitdiffstats
path: root/src/state
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-31 01:34:06 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-31 01:36:59 -0500
commit666869d90727e3d6790c979097a7de06d262fd6b (patch)
treef39e39d157de424dd5e42ff3cf6fae158cf7ed0b /src/state
parenta5179c4124e7fd8c4a1b31154d616e7a435477ae (diff)
downloadnbsh-666869d90727e3d6790c979097a7de06d262fd6b.tar.gz
nbsh-666869d90727e3d6790c979097a7de06d262fd6b.zip
also make builtins go through the pty
Diffstat (limited to 'src/state')
-rw-r--r--src/state/history/builtins.rs11
-rw-r--r--src/state/history/mod.rs94
-rw-r--r--src/state/mod.rs6
3 files changed, 64 insertions, 47 deletions
diff --git a/src/state/history/builtins.rs b/src/state/history/builtins.rs
index fd5b5c1..e4bb4c0 100644
--- a/src/state/history/builtins.rs
+++ b/src/state/history/builtins.rs
@@ -87,7 +87,7 @@ async fn cd(
home().join(path.strip_prefix(prefix).unwrap())
} else {
// TODO
- env.write_vt(b"unimplemented").await;
+ env.write_pty(b"unimplemented\n").await.unwrap();
return async_std::process::ExitStatus::from_raw(1 << 8);
}
} else {
@@ -99,16 +99,17 @@ async fn cd(
let code = match std::env::set_current_dir(&dir) {
Ok(()) => 0,
Err(e) => {
- env.write_vt(
+ env.write_pty(
format!(
- "{}: {}: {}",
+ "{}: {}: {}\n",
exe.exe(),
crate::format::io_error(&e),
dir.display()
)
.as_bytes(),
)
- .await;
+ .await
+ .unwrap();
1
}
};
@@ -144,7 +145,7 @@ async fn command(
env: &super::ProcessEnv,
) -> async_std::process::ExitStatus {
let exe = exe.shift();
- super::run_binary(&exe, env).await;
+ super::run_binary(&exe, env).await.unwrap();
*env.latest_status()
}
diff --git a/src/state/history/mod.rs b/src/state/history/mod.rs
index 9091d78..a1d5978 100644
--- a/src/state/history/mod.rs
+++ b/src/state/history/mod.rs
@@ -74,13 +74,14 @@ impl History {
entry.render_fullscreen(out);
}
+ pub async fn send_input(&mut self, idx: usize, input: Vec<u8>) {
+ self.entry(idx).await.send_input(input).await;
+ }
+
pub async fn resize(&mut self, size: (u16, u16)) {
self.size = size;
for entry in &self.entries {
- let entry = entry.lock_arc().await;
- if entry.running() {
- entry.resize.send(size).await.unwrap();
- }
+ entry.lock_arc().await.resize(size).await;
}
}
@@ -457,6 +458,12 @@ impl Entry {
}
}
+ pub async fn resize(&self, size: (u16, u16)) {
+ if self.running() {
+ self.resize.send(size).await.unwrap();
+ }
+ }
+
pub fn cmd(&self) -> &str {
match &self.ast {
Ok(ast) => ast.input_string(),
@@ -571,10 +578,6 @@ impl ProcessEnv {
self.entry.lock_arc().await
}
- async fn write_vt(&self, buf: &[u8]) {
- self.entry().await.vt.process(buf);
- }
-
async fn read_pty(&self, buf: &mut [u8]) -> std::io::Result<usize> {
(&*self.pty).read(buf).await
}
@@ -649,49 +652,38 @@ async fn run_exe(
exe: &crate::parse::Exe,
env: &ProcessEnv,
) -> async_std::process::ExitStatus {
- if let Some(status) = builtins::run(exe, env).await {
- status
- } else {
- run_binary(exe, env).await
- }
-}
-
-async fn run_binary(
- exe: &crate::parse::Exe,
- env: &ProcessEnv,
-) -> async_std::process::ExitStatus {
- let mut process = pty_process::Command::new(exe.exe());
- process.args(exe.args());
- let child = process.spawn(&env.pty);
- let child = match child {
- Ok(child) => child,
- Err(e) => {
- let mut entry = env.entry().await;
- let e_str = if let pty_process::Error::Io(e) = e {
- crate::format::io_error(&e)
+ let (exit_w, exit_r) = async_std::channel::unbounded();
+ {
+ let exe = exe.clone();
+ let env = env.clone();
+ async_std::task::spawn(async move {
+ if let Some(status) = builtins::run(&exe, &env).await {
+ exit_w.send(status).await.unwrap();
} else {
- e.to_string()
+ exit_w
+ .send(run_binary(&exe, &env).await.unwrap())
+ .await
+ .unwrap();
};
- entry.vt.process(
- format!("nbsh: {}: {}", e_str, exe.exe()).as_bytes(),
- );
- return async_std::process::ExitStatus::from_raw(1 << 8);
- }
- };
+ });
+ }
loop {
enum Res {
Read(Result<usize, std::io::Error>),
Write(Result<Vec<u8>, async_std::channel::RecvError>),
Resize(Result<(u16, u16), async_std::channel::RecvError>),
Exit(
- Result<async_std::process::ExitStatus, async_std::io::Error>,
+ Result<
+ async_std::process::ExitStatus,
+ async_std::channel::RecvError,
+ >,
),
}
let mut buf = [0_u8; 4096];
let read = async { Res::Read(env.read_pty(&mut buf).await) };
let write = async { Res::Write(env.read_input().await) };
let resize = async { Res::Resize(env.read_resize().await) };
- let exit = async { Res::Exit(child.status_no_drop().await) };
+ let exit = async { Res::Exit(exit_r.recv().await) };
match read.race(write).race(resize).or(exit).await {
Res::Read(res) => match res {
Ok(bytes) => {
@@ -748,6 +740,34 @@ async fn run_binary(
}
}
+async fn run_binary(
+ exe: &crate::parse::Exe,
+ env: &ProcessEnv,
+) -> Result<async_std::process::ExitStatus, async_std::io::Error> {
+ let mut process = pty_process::Command::new(exe.exe());
+ process.args(exe.args());
+ let child = process.spawn(&env.pty);
+ let child = match child {
+ Ok(child) => child,
+ Err(e) => {
+ let exe = exe.clone();
+ let env = env.clone();
+ let e_str = if let pty_process::Error::Io(e) = e {
+ crate::format::io_error(&e)
+ } else {
+ e.to_string()
+ };
+ env.write_pty(
+ format!("nbsh: {}: {}\n", e_str, exe.exe()).as_bytes(),
+ )
+ .await
+ .unwrap();
+ return Ok(async_std::process::ExitStatus::from_raw(1 << 8));
+ }
+ };
+ child.status_no_drop().await
+}
+
fn set_bgcolor(out: &mut impl textmode::Textmode, idx: usize, focus: bool) {
if focus {
out.set_bgcolor(textmode::Color::Rgb(0x56, 0x1b, 0x8b));
diff --git a/src/state/mod.rs b/src/state/mod.rs
index 0ac9c75..09ca113 100644
--- a/src/state/mod.rs
+++ b/src/state/mod.rs
@@ -350,11 +350,7 @@ impl State {
}
async fn handle_key_history(&mut self, key: textmode::Key, idx: usize) {
- self.history
- .entry(idx)
- .await
- .send_input(key.into_bytes())
- .await;
+ self.history.send_input(idx, key.into_bytes()).await;
}
async fn default_scene(