Fixed functions not properly forking a new process when executed in a pipeline

This commit is contained in:
2026-02-24 16:03:22 -05:00
parent b549880687
commit 59b8925de3
3 changed files with 16 additions and 20 deletions

View File

@@ -359,10 +359,12 @@ impl Dispatcher {
let func_name = argv.remove(0).span.as_str().to_string(); let func_name = argv.remove(0).span.as_str().to_string();
let argv = prepare_argv(argv)?; let argv = prepare_argv(argv)?;
let result = if let Some(func) = read_logic(|l| l.get_func(&func_name)) { let result = if let Some(ref mut func_body) = read_logic(|l| l.get_func(&func_name)) {
let _guard = ScopeGuard::exclusive_scope(Some(argv)); let _guard = ScopeGuard::exclusive_scope(Some(argv));
if let Err(e) = self.exec_brc_grp((*func).clone()) { func_body.body_mut().flags = func.flags;
if let Err(e) = self.exec_brc_grp(func_body.body().clone()) {
match e.kind() { match e.kind() {
ShErrKind::FuncReturn(code) => { ShErrKind::FuncReturn(code) => {
state::set_status(*code); state::set_status(*code);
@@ -385,7 +387,6 @@ impl Dispatcher {
result result
} }
fn exec_brc_grp(&mut self, brc_grp: Node) -> ShResult<()> { fn exec_brc_grp(&mut self, brc_grp: Node) -> ShResult<()> {
let blame = brc_grp.get_span().clone();
let NdRule::BraceGrp { body } = brc_grp.class else { let NdRule::BraceGrp { body } = brc_grp.class else {
unreachable!() unreachable!()
}; };
@@ -411,7 +412,7 @@ impl Dispatcher {
} }
}) })
} else { } else {
brc_grp_logic(self).try_blame(blame) brc_grp_logic(self)
} }
} }
fn exec_case(&mut self, case_stmt: Node) -> ShResult<()> { fn exec_case(&mut self, case_stmt: Node) -> ShResult<()> {

View File

@@ -271,11 +271,9 @@ thread_local! {
/// A shell function /// A shell function
/// ///
/// Consists of the BraceGrp Node and the stored ParsedSrc that the node refers /// Consists of the BraceGrp Node and the stored ParsedSrc that the node refers to.
/// to The Node must be stored with the ParsedSrc because the tokens of the node /// The Node must be stored with the ParsedSrc because the tokens of the node
/// contain an Arc<String> Which refers to the String held in ParsedSrc /// contain an Arc<String> Which refers to the String held in ParsedSrc
///
/// Can be dereferenced to pull out the wrapped Node
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ShFunc(Node); pub struct ShFunc(Node);
@@ -294,13 +292,12 @@ impl ShFunc {
let ConjunctNode { cmd, operator: _ } = conjunct_node; let ConjunctNode { cmd, operator: _ } = conjunct_node;
*cmd *cmd
} }
} pub fn body(&self) -> &Node {
&self.0
impl Deref for ShFunc { }
type Target = Node; pub fn body_mut(&mut self) -> &mut Node {
fn deref(&self) -> &Self::Target { &mut self.0
&self.0 }
}
} }
/// The logic table for the shell /// The logic table for the shell

View File

@@ -59,12 +59,10 @@ fn unclosed_squote() {
fn unclosed_brc_grp() { fn unclosed_brc_grp() {
let input = "{ foo bar"; let input = "{ foo bar";
let tokens = LexStream::new(Arc::new(input.into()), LexFlags::empty()) let tokens = LexStream::new(Arc::new(input.into()), LexFlags::empty())
.map(|tk| tk.unwrap()) .collect::<ShResult<Vec<_>>>();
.collect::<Vec<_>>();
let node = ParseStream::new(tokens).next().unwrap(); let Err(err) = tokens else {
let Err(err) = node else { panic!("Expected an error, got {:?}", tokens);
panic!();
}; };
let err_fmt = format!("{err}"); let err_fmt = format!("{err}");