pub fn execpline(
state: &mut estate,
slcode: wordcode,
how: i32,
last1: i32,
) -> i32Expand description
Port of execpline(Estate state, wordcode slcode, int how, int last1)
from Src/exec.c:1724-2041. Full faithful port: allocates a job-table
entry via initjob, sets up coproc mpipes, drives the whole
(multi-stage) pipeline through execpline2 (which performs the real
per-stage mpipe/fork/exec), then either spawns the job asynchronously
(Z_ASYNC -> spawnjob/deletejob) or waits synchronously
(waitjobs), including the list_pipe stop/continue fork machinery
(SUBJOB/SUPERJOB linkage) that re-forks the shell to keep an
interactively-suspended right-hand pipeline stage running.
Divergences from C, each forced by the Rust substrate and cited inline at the point of use:
initjobhere grows theVec-backed jobtab on demand and does not return -1, so C’s per-pipeline table-full bailout (c:1756-1760) is inert on THIS path. That bailout is zsh’s universal recursion backstop (initjobcaps the table atMAX_MAXJOBS→zerr("job table full or recursion limit exceeded")), which bounds recursion through paths FUNCNEST does not count (sourced files,eval— the doshfunc funcnest check at c:5684 counts FS_FUNC frames only). The fusevm runtime that actually executes pipelines does not allocate a job per pipeline, so that backstop was missing entirely — runawaysource/evalrecursion overflowed the (large but finite) main-thread stack → SIGBUS. It is reinstated inline (same ceiling, total FUNCSTACK depth as the proxy for held job slots) at the FS_SOURCE re-entry (init.rs::source) and FS_EVAL re-entry (builtin.rs eval).errbrk_saved/prev_errflag/prev_breaks(jobs.c:128 globals) are only read here; their setter lives in the not-yet-ported jobs.c reaping path, so they stay 0 and theif (errbrk_saved)restore (c:1998-2003) is a faithful no-op.