PTY: fix resource leaks and reader-isolate races (T-76)

NativePty.close() now awaits the reader-isolate spawn, kills the
child first to drive EOF on the master fd, awaits the isolate's
EOF acknowledgement, and only then closes the fd. Previously the
fd-close racing with the polling isolate left a window where the
fd number could be reused and the isolate would briefly target the
wrong file.

Both NativePty and PtySession now surface reader-isolate spawn
errors via the output stream's addError instead of silently
swallowing them.

PtySession.spawn closes the master fd on any post-receive failure,
closes parentSock in finally (was leaking on every spawn), and
kills the ptyc process if recvFd fails.

PtySession._recvFdAsync uses try/finally to close the ReceivePort
and kill the spawn isolate even when Isolate.spawn itself throws.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-05 15:10:43 +02:00
co-authored by Claude
parent 0d333e8470
commit 1787147e82
4 changed files with 244 additions and 139 deletions
+9
View File
@@ -34,6 +34,15 @@ heading, and (b) bumping `pubspec.yaml` `version:` in the same commit.
immediate EOF that looked indistinguishable from clean exit.
PTY `write` loops on short writes; both `NativePty.write` and
`PtySession.write` now throw `PtyException` on hard errors.
- PTY teardown order fixed — kill the child first so the master
fd returns EOF, await the reader isolate exit, then close the
fd. Previously closing the fd while the isolate still polled it
could briefly target a reused fd. Reader isolate spawn errors
in both `NativePty` and `PtySession` are now surfaced via the
output stream instead of silently dropped. `_recvFdAsync` no
longer leaks the `ReceivePort` when `Isolate.spawn` throws, and
`PtySession.spawn` closes the master fd if any post-receive
step fails.
### Security