summaryrefslogtreecommitdiffstats
path: root/src/pipeline/builtins/command.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-01-05 17:10:37 -0500
committerJesse Luehrs <doy@tozt.net>2022-01-05 17:10:37 -0500
commitc4b5c55eba3e5782b1be575c62067dcfeac08599 (patch)
tree4c5a144e1f5b3e6a54749ac5aefae04ce8ce1b26 /src/pipeline/builtins/command.rs
parentc86400ecb67614846eae2d4bf47f71f50263100a (diff)
downloadnbsh-c4b5c55eba3e5782b1be575c62067dcfeac08599.tar.gz
nbsh-c4b5c55eba3e5782b1be575c62067dcfeac08599.zip
also support redirection for builtins
Diffstat (limited to 'src/pipeline/builtins/command.rs')
-rw-r--r--src/pipeline/builtins/command.rs41
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;