Skip to content

Shell alias runner deadlocks on large output and reports signal-killed aliases as exit 0 #1756

Description

@sneg55

Shell-alias runner deadlocks on large output and reports signal-killed aliases as success

Context: API Makeathon participant. Found while reviewing the alias subprocess runner in src/main.rs.

Two independent bugs in how the alias runner spawns and reaps its child process.

1. Deadlock on large output

src/main.rs:226-234 pipes both the child's stdout and stderr, then calls wait() (line 232) before either stream is drained (lines 234-245). Once either OS pipe buffer fills, the child blocks writing while the parent blocks in wait() waiting for the child to exit. Neither side makes progress.

2. Signal-killed alias reported as exit 0

src/main.rs:232-247 converts ExitStatus::code() with unwrap_or(0). On Unix, a process terminated by a signal has code() == None, so abnormal termination is converted to exit code 0. That value becomes Zoo's own exit status (src/main.rs:203).

Concrete failure

A shell alias that emits more than one pipe buffer of stdout or stderr never completes (it hangs at wait()). A shell alias killed by a signal (kill -TERM $$, an OOM kill, a segfault) is reported as a clean success, so scripts continue as though it worked.

Verify

Deadlock: define an alias that emits data beyond pipe capacity; the command blocks at wait(), while a control implementation using wait_with_output() or concurrent draining completes and preserves the output. Signal: define an alias running kill -TERM $$, invoke it, and inspect Zoo's exit status (currently 0).

Suggested fix

Use wait_with_output() (or drain the pipes on separate threads before waiting), and map signal termination to a nonzero exit (e.g. 128 + signal) instead of unwrap_or(0).

Environment

Zoo CLI v0.2.184 (33534cd). Reviewed against the current main of KittyCAD/cli.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions