fix: open write handles O_RDWR so read-during-build works - #27
fix: open write handles O_RDWR so read-during-build works#27winst0niuss wants to merge 1 commit into
Conversation
SDCardManager::openFileForWrite on device opens O_RDWR | O_CREAT | O_TRUNC. The simulator used O_WRONLY, so any firmware path that reads back from a still-open write handle got EBADF. Section::loadPageDuringBuild does exactly that: while a section .bin is being built it seeks into that same handle to deserialize an already-written page. Under O_WRONLY the read fails and the reader renders a blank page, which shows up as an empty screen on first entry into a chapter. Re-entering the chapter works because the build has finished by then and pages are served from a separate read handle.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (3)src/Hal*.{cpp,h}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/HalStorage.cpp📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/**/*.{cpp,h}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🔇 Additional comments (1)
📝 WalkthroughWalkthrough
ChangesStorage access
Estimated code review effort: 1 (Trivial) | ~2 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Entering a not-yet-paginated chapter renders a blank page. Going back to the previous chapter and forward again shows the text. Only the simulator is affected — the same firmware is fine on device.
Cause
openFileForWriteopens the file write-only, while the device SDK opens it read-write:SDCardManager::openFileForWrite(device)O_RDWR | O_CREAT | O_TRUNCHalStorage::openFileForWrite(simulator, before this PR)O_WRONLY | O_CREAT | O_TRUNCFirmware reads back from a write handle while it is still open.
Section::loadPageDuringBuilddoes exactly that — while a section.binis being built it seeks into that same handle to deserialize a page it has already written, then restores the write cursor:On a write-only fd that read fails,
Page::deserializeyields nothing, and the reader paints an empty page.The recovery path explains why re-entry works: once the build has finalized,
Section::loadPageroutes toloadPageAt, which opens its own handle throughopenFileForRead(O_RDONLY) and reads normally.Reproducing
Open a book with chapters long enough that pagination does not finish instantly, and page forward into a fresh chapter. With a warm cache the build is already done, so clear
fs_/.crosspoint/epub_*first.First entry — blank, and the page counter is prefixed with
~because the section is still being laid out:Same chapter after going back and forward again — the build has finished, the count is exact, the text is there:
Logs show the build being cut short on first entry (pages 0-7 laid out, then a render), and completing on the second (
[EHP] Time to parse and build pages: 186 ms, pages 0-69).Fix
One line, plus a comment recording why the mode matters. Verified by hand: with the fix, a fresh chapter renders its text on first entry.
This may be the remaining half of the
std::fstreambugs listed in.claude/CONTEXT-sim-notes.mdunder "Ebook reader showed nothing on first press (and 'double press required' symptom)" — those were fixed by movingHalFile::Implto POSIX fds, but the write-only open mode stayed.