summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-01-17 00:11:52 -0500
committerJesse Luehrs <doy@tozt.net>2022-01-17 00:22:16 -0500
commit296fa4ce873c158b8c87d21db3e566c8ae365504 (patch)
tree853fdd6ff652c4be9d94830b9ee615a8ac4f8784
parente7d8a9f7d234cb2b8a6691c5a2e33f2b18776a3d (diff)
downloadnbsh-296fa4ce873c158b8c87d21db3e566c8ae365504.tar.gz
nbsh-296fa4ce873c158b8c87d21db3e566c8ae365504.zip
stop sending environment stuff over a pipe
sending it through the actual environment should be sufficient
-rw-r--r--src/env.rs38
-rw-r--r--src/main.rs5
-rw-r--r--src/runner/mod.rs28
-rw-r--r--src/shell/history/mod.rs26
4 files changed, 33 insertions, 64 deletions
diff --git a/src/env.rs b/src/env.rs
index b612d60..3a6d8b5 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -21,14 +21,18 @@ impl Env {
Ok(Self::V0(V0 {
pwd: pwd.clone(),
vars: std::env::vars_os()
- .chain(
- [
- (__NBSH_IDX.into(), "0".into()),
- (__NBSH_LATEST_STATUS.into(), "0".into()),
- (__NBSH_PREV_PWD.into(), pwd.into()),
- ]
- .into_iter(),
- )
+ .chain(Self::defaults(pwd).into_iter())
+ .collect(),
+ }))
+ }
+
+ pub fn new_from_env() -> anyhow::Result<Self> {
+ let pwd = std::env::current_dir()?;
+ Ok(Self::V0(V0 {
+ pwd: pwd.clone(),
+ vars: Self::defaults(pwd)
+ .into_iter()
+ .chain(std::env::vars_os())
.collect(),
}))
}
@@ -118,14 +122,6 @@ impl Env {
Ok(())
}
- pub fn as_bytes(&self) -> Vec<u8> {
- bincode::serialize(self).unwrap()
- }
-
- pub fn from_bytes(bytes: &[u8]) -> Self {
- bincode::deserialize(bytes).unwrap()
- }
-
fn special_var(&self, k: &str) -> Option<String> {
Some(match k {
"$" => crate::info::pid(),
@@ -142,4 +138,14 @@ impl Env {
_ => return None,
})
}
+
+ fn defaults(
+ pwd: std::path::PathBuf,
+ ) -> [(std::ffi::OsString, std::ffi::OsString); 3] {
+ [
+ (__NBSH_IDX.into(), "0".into()),
+ (__NBSH_LATEST_STATUS.into(), "0".into()),
+ (__NBSH_PREV_PWD.into(), pwd.into()),
+ ]
+ }
}
diff --git a/src/main.rs b/src/main.rs
index 64685a8..b65fb1e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -25,8 +25,9 @@ mod runner;
mod shell;
async fn async_main() -> anyhow::Result<i32> {
- if std::env::args().nth(1).as_deref() == Some("--internal-cmd-runner") {
- return runner::main().await;
+ if std::env::args().nth(1).as_deref() == Some("-c") {
+ return runner::run(std::env::args().nth(2).as_deref().unwrap())
+ .await;
}
shell::main().await
diff --git a/src/runner/mod.rs b/src/runner/mod.rs
index 21ed9c9..48d66ad 100644
--- a/src/runner/mod.rs
+++ b/src/runner/mod.rs
@@ -69,16 +69,14 @@ enum Frame {
For(bool, usize, Vec<String>),
}
-pub async fn main() -> anyhow::Result<i32> {
- // Safety: we don't create File instances for or read/write data on fds
- // 3 or 4 anywhere else
- let shell_read = unsafe { async_std::fs::File::from_raw_fd(3) };
- let shell_write = unsafe { async_std::fs::File::from_raw_fd(4) };
+pub async fn run(commands: &str) -> anyhow::Result<i32> {
+ // Safety: we don't create File instances for or read/write data on fd
+ // 3 anywhere else
+ let shell_write = unsafe { async_std::fs::File::from_raw_fd(3) };
cloexec(3)?;
- cloexec(4)?;
- let (commands, mut env) = read_data(shell_read).await?;
- run_commands(&commands, &mut env, &shell_write).await?;
+ let mut env = Env::new_from_env()?;
+ run_commands(commands, &mut env, &shell_write).await?;
let status = env.latest_status();
write_event(&shell_write, Event::Exit(env)).await?;
@@ -221,20 +219,6 @@ async fn run_pipeline(
Ok(())
}
-async fn read_data(
- mut fh: async_std::fs::File,
-) -> anyhow::Result<(String, Env)> {
- let mut data = vec![];
- fh.read_to_end(&mut data).await?;
- let commands = bincode::deserialize(&data).unwrap();
- let len: usize = bincode::serialized_size(&commands)
- .unwrap()
- .try_into()
- .unwrap();
- let env = Env::from_bytes(&data[len..]);
- Ok((commands, env))
-}
-
async fn write_event(
mut fh: &async_std::fs::File,
event: Event,
diff --git a/src/shell/history/mod.rs b/src/shell/history/mod.rs
index 2863cad..ad83e92 100644
--- a/src/shell/history/mod.rs
+++ b/src/shell/history/mod.rs
@@ -283,31 +283,19 @@ async fn spawn_commands(
event_w: async_std::channel::Sender<Event>,
) -> anyhow::Result<async_std::process::ExitStatus> {
let mut cmd = pty_process::Command::new(std::env::current_exe()?);
- cmd.arg("--internal-cmd-runner");
+ cmd.args(&["-c", cmdline]);
env.apply(&mut cmd);
- let (to_r, to_w) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
let (from_r, from_w) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
// Safety: dup2 is an async-signal-safe function
unsafe {
cmd.pre_exec(move || {
- nix::unistd::dup2(to_r, 3)?;
- nix::unistd::dup2(from_w, 4)?;
+ nix::unistd::dup2(from_w, 3)?;
Ok(())
});
}
let child = pty.spawn(cmd)?;
- nix::unistd::close(to_r)?;
nix::unistd::close(from_w)?;
- // Safety: to_w was just opened above, was not used until now, and can't
- // be used after this because from_raw_fd takes it by move
- write_env(
- unsafe { async_std::fs::File::from_raw_fd(to_w) },
- cmdline,
- env,
- )
- .await?;
-
let (read_w, read_r) = async_std::channel::unbounded();
let new_read = move || {
let read_w = read_w.clone();
@@ -394,13 +382,3 @@ async fn spawn_commands(
}
}
}
-
-async fn write_env(
- mut to_w: async_std::fs::File,
- pipeline: &str,
- env: &Env,
-) -> anyhow::Result<()> {
- to_w.write_all(&bincode::serialize(pipeline)?).await?;
- to_w.write_all(&env.as_bytes()).await?;
- Ok(())
-}