Skip to content

add st_fcheck and st_fclose, for output whose write can fail - #27

Open
glennhickey wants to merge 2 commits into
masterfrom
write-error-checking
Open

add st_fcheck and st_fclose, for output whose write can fail#27
glennhickey wants to merge 2 commits into
masterfrom
write-error-checking

Conversation

@glennhickey

Copy link
Copy Markdown
Contributor

Add some explicit checks to detect situations when writing to a full disk. The idea is to fail rather than silently truncating output.

glennhickey and others added 2 commits August 10, 2026 11:26
stdio reports a failed write -- ENOSPC, a quota, a read-only mount -- by
setting the stream's error indicator, and nothing is obliged to look at it.
A program that writes an output file and never checks therefore cannot tell
a complete file from a truncated one, and still exits successfully. When the
format is line oriented, as most of ours are, the short file also still
parses: a truncated fasta is a valid fasta with less sequence in it.

This is not hypothetical. Red hit exactly this in a VGP 577-way cactus
alignment, silently losing up to 473 Mb from a 2.1 Gb genome across 9
genomes, all preprocessed on one node inside a 42 minute window.

st_fcheck flushes and then tests the indicator; the flush is part of the
check rather than an optimisation, because the buffer is not necessarily
handed to the operating system until it happens, so a stream that has
already lost data can still look clean beforehand. st_fclose adds a close
whose return value is also checked, closing being the last point at which
buffered data reaches the operating system and so the only place a failure
there is ever reported. Both die via the existing st_errAbort/st_errnoAbort
path, matching st_fopen, which is the neighbouring wrapper they are meant to
pair with.

Purely additive: no existing caller changes behaviour. Callers get converted
separately.

Tested with a child process writing to /dev/full, where every write fails
with ENOSPC. Before, the write returned and the stream looked fine; now the
child dies with status 1 naming the file. The happy path is asserted to be
untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The test distinguished only "no /dev/full" from "the real /dev/full". A third
case exists: a rootfs unpacked without device nodes, or a sandbox that stubs
/dev, leaves a plain writable file at that path. There the write succeeds,
st_fcheck correctly returns, and the test reports a failure that says nothing
about st_fcheck. Prove the device is the one we think it is, with a raw write
that has to fail with ENOSPC, and treat anything else as a skip.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant