Skip to content

wasi: a Ctrl-C Interrupt record on guest stdio is treated as a protocol error and closes all three streams #28

Open

Description

@SnowCheetos

Finding (confirmed by reading; live in kore main's composition)

crates/wasi/src/stdio.rs's Shared::receive handles only Data and Closed records. Anything else falls to _ => lost = Protocol (stdio.rs:107). After that, all three guest streams return StreamError::Closed (stdio.rs:296-391), and the receive loop stops (while self.lost.is_none(), stdio.rs:88).

The Interrupt record is legal at any time per kore's process ABI (crates/abi/src/process.rs:166-174, 248-250 in kore). It is sent by:

  • the terminal window (crates/stream-host/src/lib.rs:579/617/647);
  • the shell's interrupt_child (user/apps/shell/src/main.rs:1579).

User-visible result: Ctrl-C on wasm <guest> ends the guest with stdio lost: Protocol (user/apps/utils/wasm/src/main.rs:299 in kore). It does not deliver an interrupt.

Interaction with the parent's grace: reading the first interrupt record ends the parent's unread-interrupt grace (crates/rt/src/process/interrupt.rs:12-15 in kore). Because later records are never read, a third Ctrl-C, or 60 s after the second, still revokes.

kore main composes exactly this adapter. user/Cargo.toml pins kore-wasi from libkore, and its [patch] maps kore-abi to kore's in-tree ABI, which has carried Interrupt since kore a2866d761 (2026-09-29).

Suggested fix

  • Decode Interrupt in receive and record a distinct interrupted state, not Protocol, that keeps any outstanding InputReady.
  • Connect that state to the guest's interrupt/cancellation policy, so the host can end the guest cleanly or surface the interrupt to it.
  • Add a host test feeding an Interrupt record between Data records.

Surfaced by Copilot's review of #27 (that PR only re-exports native/; this adapter is unchanged there).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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