Skip to content

Unix PTY Lifecycle Can Signal Reused PIDs and Drop Final Output #1926

Description

@rawkode

Summary

At rio revision 7ae087500bcde5c0c9f09cb9c50382e9220b3360, the Unix PTY path has two independently actionable lifecycle defects:

  1. a reaped child can later be signalled through its saved numeric PID;
  2. final PTY output can be lost during exit under terminal-state lock contention.

Final-Output Failure

A real PTY child can write a final marker, exit 0, emit child-exit/close, and leave the marker absent from the final frame. This is reproduced with coordinated snapshot-lock contention (timing-dependent).

Machine::pty_read buffers bytes locally. After failed lock acquisition it may read again; Linux PTY hangup may then yield EIO. The error path returns before the already-read bytes reach the parser. This mechanism is source-backed and consistent with the failure; the regression does not prove the exact syscall sequence.

Child Lifecycle Risk

Child::waitpid(&self) reaps without recording completion; Child::drop unconditionally sends SIGHUP to the saved PID. PID reuse can therefore signal an unrelated process. This is a source-level risk, not an observed incident. PID reuse does not cause the output-loss failure.

API Boundary

Pty.child and Child.pid are public, but Child.process, Machine.pty, and State.parser are private. There is no small ownership-safe repair while retaining Machine<Pty, Listener>. A custom EIO-to-EOF reader only mitigates one path.

Expected Repair

  • Make termination/reap explicit, idempotent, status-preserving, and incapable of signalling after reap.
  • Parse/preserve all buffered bytes before EOF/HUP/error; publish exit only after final drain and pending synchronized updates.
  • Define bounded handling for descendants holding the slave open.

Regression Coverage

Add a synthetic EventedPty bytes → EIO test under lock contention; EOF/HUP residual output; parsing-budget and pending-sync cases; plus real-child natural exit, repeated close, ignored SIGHUP, reap completion, setup/reader failures, and no post-reap signal.

Happy to provide the embedding-side regression harness.

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions