win32: stop erasing the real ReadFile error — pread failures name their WinErr (#307)

compat_pread mapped every non-EOF ReadFile failure to EIO, so the field report
was always the same three words: "Input/output error". #307 then burned three
rounds of guessing across three people — storage? contention? alignment? —
because the actual GetLastError code never appeared anywhere.

compat_pread now stashes the code in a per-thread slot and pread_full appends
it to the failure line:

    pread qs: Input/output error (off 780592, 0/8192 bytes, WinErr=1450)

That one number is the difference between "insufficient system resources"
(1450 -> memory pressure), "sharing violation" (32 -> AV interference),
"device not ready" (21 -> the T: drive itself) and a dozen other distinct
diagnoses. Diagnostic only: no behavior change, no retry policy — that
discussion lives in #361 and should be settled AFTER the first report tells
us which error we are actually retrying.

Linux path untouched byte-for-byte; the Windows compile is certified by the
check.yml MSYS2 job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
JustVugg
2026-07-17 18:49:28 +02:00
parent d5327e2252
commit 211d4488c3
2 changed files with 14 additions and 1 deletions
+7 -1
View File
@@ -1732,8 +1732,14 @@ static int pread_full(int fd, void *buf, int64_t n, int64_t off, const char *tag
while(got<n){
ssize_t r=pread(fd, p+got, (size_t)(n-got), off+got);
if(r<0){ if(errno==EINTR) continue;
#ifdef _WIN32
fprintf(stderr,"%s: %s (off %lld, %lld/%lld bytes, WinErr=%lu)\n",tag,strerror(errno),
(long long)off,(long long)got,(long long)n,(unsigned long)compat_pread_lasterr);
#else
fprintf(stderr,"%s: %s (off %lld, %lld/%lld bytes)\n",tag,strerror(errno),
(long long)off,(long long)got,(long long)n); return -1; }
(long long)off,(long long)got,(long long)n);
#endif
return -1; }
if(r==0){ fprintf(stderr,"%s: short read at EOF (off %lld, %lld/%lld bytes) — truncated shard?\n",
tag,(long long)off,(long long)got,(long long)n); return -1; }
got+=r;