Repository navigation
Wait for the detached child to exit before reading its stdin payload - #1109
Conversation
…1108) Windows refuses a reader while cmd still holds the redirect open for write, and the file is non-empty before that handle closes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
PR Summary by QodoWait for detached child exit before reading stdin payload
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Child termination bypasses identity helper
|
| try { | ||
| using var process = Process.GetProcessById(pid); | ||
| await process.WaitForExitAsync(exitBound.Token); | ||
| } catch (ArgumentException) { |
There was a problem hiding this comment.
1. Child termination bypasses identity helper 📘 Rule violation ☼ Reliability
The detached-child test captures child.Pid, reconstructs a Process with Process.GetProcessById(pid), waits on it, and later calls Kill(pid) instead of using PidIdentity.Capture and the retained DetachedChild identity-aware termination helpers. After the child exits, Windows may reuse the PID before the lookup, causing the test to wait on an unrelated process or time out before reading the payload, while raw-PID cleanup also lacks ownership-safe checks.
Agent Prompt
## Issue description
The detached-child test waits for termination by looking up and waiting on a raw PID after closing stdin, and performs raw PID cleanup instead of using the shared process-identity abstraction or retained process handle. Since Windows can reuse the PID after the child exits, `Process.GetProcessById(pid)` can target an unrelated process; preserve the child's identity for liveness, waiting, and termination while retaining the existing timeout cancellation and cleanup behavior.
## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/ProcessHelpersDetachedStdinTests.cs[39-53]
- test/Capacitor.Cli.Tests.Unit/ProcessHelpersDetachedStdinTests.cs[45-50]
- src/Capacitor.Cli/DetachedChild.cs[15-49]
- src/Capacitor.Cli/ProcessHelpers.WindowsSpawn.cs[150-165]
## Recommended Fix
Capture the detached child with `PidIdentity.Capture` while it is alive and wait with `WaitUntilGoneAsync`, `IsGone`, or an equivalent identity-aware operation. Alternatively, expose an internal wait operation or process-backed wait handle on `DetachedChild` that uses its retained Windows process handle, and use that identity-preserving wait instead of `Process.GetProcessById(pid)`; update cleanup to use the approved process-tree or identity abstraction rather than raw PID operations while retaining timeout cancellation and cleanup behavior.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| } | ||
|
|
||
| var deadline = DateTime.UtcNow.AddSeconds(10); | ||
| // Read only once the child has exited: until cmd closes its redirect the file is open |
There was a problem hiding this comment.
2. The pull request title lacks its issue reference 📘 Rule violation ⚙ Maintainability
The pull request title is Wait for the detached child to exit before reading its stdin payload and does not end with a GitHub issue reference in parentheses. The title is therefore missing the required (#<digits>) suffix even though the supplied commit subject includes (#1108).
Agent Prompt
## Issue description
The pull request title does not include the required GitHub issue reference suffix.
## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/ProcessHelpersDetachedStdinTests.cs[39-39]
## Recommended Fix
Update the pull request title to a single imperative clause ending with the explicit GitHub issue reference, for example `Wait for the detached child to exit before reading its stdin payload (#1108)`, and keep the total subject at or below 80 characters.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Closes #1108 — AI-3122
What & why
The_payload_reaches_the_childs_stdinpolls until the child's output file is non-empty, then reads it withFile.ReadAllText.morewrites the payload beforecmdcloses its>redirect, so on a slow runner the read lands while the file is still open for write, and Windows' mandatory sharing refuses it. The test now waits for the child to exit before reading, so the redirect handle is closed by construction; it also rules out reading a partial write.Where to look
The pid lookup is safe here only because
DetachedChildholds the process handle, which keeps the pid from being reused; a lookup that throws means the child is already gone, which is the state being waited for.Verification
windows-latestfor PR Keep local terminals responsive when the cloud terminal mirror stalls #1096 (runs 35700576106 and 35719445826), which does not touch this project, and once alone was the leg's only failure out of 15,064 tests.dotnet build test/Capacitor.Cli.Tests.Unit, 0 warnings); the test itself is Windows-only, so this PR's own Windows leg is the run that exercises it.🤖 Generated with Claude Code