Skip to content

Implement streaming I/O for external command execution #49

@cdprice02

Description

@cdprice02

Background

The current plan for issue #9 (wire executable I/O through ShellIo) uses Command::output(), which buffers the child process's entire stdout/stderr before writing it to ShellIo. This is correct but not streaming — output is held in memory until the child exits.

For a performant shell, output should be forwarded to the caller incrementally as the child produces it, rather than buffered entirely in memory.

Problem

ShellIo::out_writer() returns &mut dyn Write, and std::process::Command accepts Stdio (file handles, pipes, or inherit) — there is no way to hand a dyn Write directly to the OS-level pipe. Bridging the two requires either:

  • A dedicated reader thread per child stream (stdout + stderr), copying bytes from the pipe read end into ShellIo as they arrive
  • An async/io-uring approach for non-blocking I/O multiplexing

Acceptance Criteria

  • External command stdout and stderr are forwarded to ShellIo incrementally (no full-output buffering)
  • MockIo still captures all output correctly in tests
  • Works for both StandardIo (real terminal) and MockIo (test harness)
  • Large output (e.g., piping a multi-GB file) does not cause excessive memory use
  • No regression on existing executable I/O tests

Notes

  • Blocked by / should follow Wire executable I/O through ShellIo #9, which establishes the basic ShellIo wiring
  • Threading approach is likely simplest for now; async can be revisited later
  • stdin forwarding (interactive child processes) is a related but separate concern

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrefactorImprove the codebase

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions