Skip to main content

runshfunc

Function runshfunc 

Source
pub fn runshfunc(
    _prog: Option<&eprog>,
    wrap: usize,
    name: &str,
    body: &mut dyn FnMut() -> i32,
) -> i32
Expand description

Port of runshfunc() from Src/exec.c:6166 — C decl runshfunc(Eprog prog, FuncWrap wrap, char *name). the wrapper-chain walk that stands between doshfunc and a function body. C:

queue_signals();
ou = zalloc(ouu = underscoreused);
if (ou) memcpy(ou, zunderscore, underscoreused);
while (wrap) {                       // wrapper chain
    wrap->module->wrapper++;
    cont = wrap->handler(prog, wrap->next, name);
    wrap->module->wrapper--;
    if (!wrap->module->wrapper && (wrap->module->node.flags & MOD_UNLOAD))
        unload_module(wrap->module);
    if (!cont) {                     // wrapper handled it
        if (ou) zfree(ou, ouu);
        unqueue_signals();
        return;
    }
    wrap = wrap->next;
}
startparamscope();
execode(prog, 1, 0, "shfunc");
if (ou) { setunderscore(ou); zfree(ou, ouu); }
endparamscope();
unqueue_signals();

RUST-ONLY ADAPTATION — what this port does and does NOT own. When zshrs replaced C’s wordcode walk with a body delegate, everything in the listing above except the chain walk moved into doshfunc, which is the only caller:

C lineWhere it lives in zshrs
c:6171 / c:6202 queue_signals / unqueue_signalsdoshfunc’s own outer pair (c:5835 / c:6128) already brackets this window; C’s inner pair is a nested refcount bump inside it
c:6173-6175 / c:6196-6198 $_ save / setunderscoredoshfunc, around this call (saved_zunderscore)
c:6194 startparamscope()doshfunc — inc_locallevel() before the funcstack push
c:6200 endparamscope()doshfunc’s epilogue
c:6195 execode(prog, 1, 0, "shfunc")the body delegate

Duplicating any of them here would double-apply it, so the body below is c:6177-6193 plus the c:6195 body call, and nothing else.

WARNING: param names don’t match C — Rust=(_prog, wrap, name, body) vs C=(prog, wrap, name). wrap is an INDEX into [BODY_WRAPPERS] rather than a FuncWrap pointer (a Vec-shaped chain has no ->next to hand out); wrap = 0 is C’s wrappers head and wrap = i + 1 is the wrap->next a handler re-enters with. _prog is unused because the body arrives as body, and the return value is the body’s exit status (C returns void and communicates through lastval).