diff options
author | Jesse Luehrs <doy@tozt.net> | 2022-01-17 00:11:52 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2022-01-17 00:22:16 -0500 |
commit | 296fa4ce873c158b8c87d21db3e566c8ae365504 (patch) | |
tree | 853fdd6ff652c4be9d94830b9ee615a8ac4f8784 | |
parent | e7d8a9f7d234cb2b8a6691c5a2e33f2b18776a3d (diff) | |
download | nbsh-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.rs | 38 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/runner/mod.rs | 28 | ||||
-rw-r--r-- | src/shell/history/mod.rs | 26 |
4 files changed, 33 insertions, 64 deletions
@@ -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(()) -} |