Add EINTR handling for std.stdio and std.process#11007
Merged
thewilsonator merged 4 commits intodlang:masterfrom May 6, 2026
Merged
Add EINTR handling for std.stdio and std.process#11007thewilsonator merged 4 commits intodlang:masterfrom
thewilsonator merged 4 commits intodlang:masterfrom
Conversation
Introduces a new package(std) module providing two composable retry primitives for interrupted system calls: - retryOnEINTR: loops while a one-shot syscall returns an error sentinel and errno == EINTR; propagates the final result to the caller. - retryShortIO: drives a partial-progress I/O loop (à la fwrite/posix.write) until all bytes are transferred or a non-transient error occurs; accepts an optional onEINTR hook (clearerr discipline for stdio call sites). Replaces the nested retryInterrupted template in std.process and provides the primitive for fixing std.stdio's EINTR-prone write paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The byte-array fast path of LockingTextWriter.put throws ErrnoException when fwrite reports a short write, matching the writer's documented contract. The per-character fall-through path discarded the return values of fputc/fputwc, so write errors (closed/broken pipe, full disk, EBADF, etc.) corrupted output silently. Wrap the underlying calls in putcChecked / putwcChecked so the per-character path raises the same ErrnoException as the byte-array path. Demonstrated by the new /dev/full test. dlang#11005
…rites A signal whose handler does not carry SA_RESTART can interrupt fwrite(3) mid-write, causing it to return a short count with errno == EINTR and the stream's error indicator set. Three write paths in std.stdio treated this as fatal: LockingTextWriter.put (byte-array fast path and per-character paths), File.rawWrite, and BinaryWriterImpl.rawWrite. Programs would crash on the next writeln after a signal landed mid-flush. Wrap the underlying fwrite/fputc/fputwc calls in std.internal.retry's retryShortIO and retryOnEINTR so EINTR is transparently retried until the buffer is fully written or a non-transient error occurs. dlang#11006
Removes the local nested retryInterrupted template in spawnProcessPosix and switches its three call sites to the shared retryOnEINTR helper. Pure refactor — semantics are identical.
Contributor
thewilsonator
left a comment
There was a problem hiding this comment.
ping when this is no longer draft
Member
Author
|
@thewilsonator Thanks, was waiting for CI. Ready for review. |
thewilsonator
approved these changes
May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11006. As a bonus, also fixes #11005 (bug was noticed during implementation).