properly implemented read builtin

fixed bugs related to redirections and compound commands

improved io routing logic
This commit is contained in:
2026-02-17 17:30:21 -05:00
parent 12f36283ca
commit 87d465034a
16 changed files with 499 additions and 170 deletions

View File

@@ -4,11 +4,9 @@ use crate::{
jobs::{ChildProc, JobBldr},
libsh::error::ShResult,
parse::{
execute::prepare_argv,
lex::{Span, Tk},
Redir,
Redir, execute::prepare_argv, lex::{Span, Tk}
},
procio::{IoFrame, IoStack},
procio::{IoFrame, IoStack, RedirGuard},
};
pub mod alias;
@@ -21,12 +19,15 @@ pub mod pwd;
pub mod shift;
pub mod shopt;
pub mod source;
pub mod test;
pub mod zoltraak; // [[ ]] thing
pub mod test; // [[ ]] thing
pub mod read;
pub mod zoltraak;
pub const BUILTINS: [&str; 19] = [
"echo", "cd", "export", "pwd", "source", "shift", "jobs", "fg", "bg", "alias", "unalias",
"return", "break", "continue", "exit", "zoltraak", "shopt", "builtin", "command",
pub const BUILTINS: [&str; 20] = [
"echo", "cd", "read", "export", "pwd", "source",
"shift", "jobs", "fg", "bg", "alias", "unalias",
"return", "break", "continue", "exit", "zoltraak",
"shopt", "builtin", "command",
];
/// Sets up a builtin command
@@ -56,7 +57,7 @@ pub const BUILTINS: [&str; 19] = [
/// * If redirections are given, the second field of the resulting tuple will
/// *always* be `Some()`
/// * If no redirections are given, the second field will *always* be `None`
type SetupReturns = ShResult<(Vec<(String, Span)>, Option<IoFrame>)>;
type SetupReturns = ShResult<(Vec<(String, Span)>, Option<RedirGuard>)>;
pub fn setup_builtin(
argv: Vec<Tk>,
job: &mut JobBldr,
@@ -74,16 +75,16 @@ pub fn setup_builtin(
let child = ChildProc::new(Pid::this(), Some(&cmd_name), Some(child_pgid))?;
job.push_child(child);
let io_frame = if let Some((io_stack, redirs)) = io_mode {
let guard = if let Some((io_stack, redirs)) = io_mode {
io_stack.append_to_frame(redirs);
let mut io_frame = io_stack.pop_frame();
io_frame.redirect()?;
Some(io_frame)
let io_frame = io_stack.pop_frame();
let guard = io_frame.redirect()?;
Some(guard)
} else {
None
};
// We return the io_frame because the caller needs to also call
// io_frame.restore()
Ok((argv, io_frame))
Ok((argv, guard))
}