pub fn runshfunc(
_prog: Option<&eprog>,
wrap: usize,
name: &str,
body: &mut dyn FnMut() -> i32,
) -> i32Expand 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 line | Where it lives in zshrs |
|---|---|
c:6171 / c:6202 queue_signals / unqueue_signals | doshfunc’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 / setunderscore | doshfunc, 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).