diff options
author | Jesse Luehrs <doy@tozt.net> | 2022-01-05 17:10:37 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2022-01-05 17:10:37 -0500 |
commit | c4b5c55eba3e5782b1be575c62067dcfeac08599 (patch) | |
tree | 4c5a144e1f5b3e6a54749ac5aefae04ce8ce1b26 /src/pipeline/builtins | |
parent | c86400ecb67614846eae2d4bf47f71f50263100a (diff) | |
download | nbsh-c4b5c55eba3e5782b1be575c62067dcfeac08599.tar.gz nbsh-c4b5c55eba3e5782b1be575c62067dcfeac08599.zip |
also support redirection for builtins
Diffstat (limited to 'src/pipeline/builtins')
-rw-r--r-- | src/pipeline/builtins/command.rs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/pipeline/builtins/command.rs b/src/pipeline/builtins/command.rs index fd5e322..d65dd1c 100644 --- a/src/pipeline/builtins/command.rs +++ b/src/pipeline/builtins/command.rs @@ -40,6 +40,10 @@ impl Command { self.io.pre_exec(f); } + pub fn apply_redirects(&mut self, redirects: &[crate::parse::Redirect]) { + self.io.apply_redirects(redirects); + } + pub fn spawn(self, env: &Env) -> anyhow::Result<Child> { let Self { f, exe, io } = self; (f)(exe, env, io) @@ -131,6 +135,43 @@ impl Io { self.pre_exec = Some(Box::new(f)); } + pub fn apply_redirects(&mut self, redirects: &[crate::parse::Redirect]) { + for redirect in redirects { + match &redirect.to { + crate::parse::RedirectTarget::Fd(fd) => { + self.fds.insert(redirect.from, self.fds[fd]); + } + crate::parse::RedirectTarget::File(path) => { + use nix::fcntl::OFlag; + use nix::sys::stat::Mode; + let fd = match redirect.dir { + crate::parse::Direction::In => nix::fcntl::open( + path, + OFlag::O_NOCTTY | OFlag::O_RDONLY, + Mode::empty(), + ) + .unwrap(), + crate::parse::Direction::Out => nix::fcntl::open( + path, + OFlag::O_CREAT + | OFlag::O_NOCTTY + | OFlag::O_WRONLY + | OFlag::O_TRUNC, + Mode::S_IRUSR + | Mode::S_IWUSR + | Mode::S_IRGRP + | Mode::S_IWGRP + | Mode::S_IROTH + | Mode::S_IWOTH, + ) + .unwrap(), + }; + self.fds.insert(redirect.from, fd); + } + } + } + } + pub async fn read_stdin(&self, buf: &mut [u8]) -> anyhow::Result<usize> { if let Some(mut fh) = self.stdin() { let res = fh.read(buf).await; |