Skip to content

bridge: fbuild_core::fs::write_atomic for state files (#844) #846

Description

@zackees

Goal

State files written with bare std::fs::write corrupt on partial-write (crash, OOM, SIGKILL). Provide an atomic-write bridge and migrate every state-file writer to use it.

Sub-issue of #844.

Bridge API

fbuild_core::fs::write_atomic(path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Result<()> that:

  1. Writes content to <path>.tmp.<pid>.<nonce>.
  2. Calls File::sync_all() to flush the write.
  3. Atomically renames to the final path.
  4. On Windows, uses MoveFileExW with MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH.

Migration targets (HIGH risk: corruption blocks rebuilds)

  • crates/fbuild-build/src/build_info.rs:291std::fs::write(path, &json) (build fingerprint JSON)
  • crates/fbuild-packages/src/toolchain/esp32_metadata.rs:236,247,273,283 — framework discovery cache JSONs
  • crates/fbuild-cli/src/cli/symbols_cmd.rs:180 — symbol dump
  • crates/fbuild-cli/src/cli/clang_tools.rs:206 — IWYU database
  • crates/fbuild-cli/src/cli/clangd_config.rs:87 — IDE config

Already correct (do not touch)

  • crates/fbuild-daemon/src/status_manager.rs:211 — already uses tempfile + rename pattern (the reference implementation).

Lint

After the migration: ban std::fs::write in code paths that touch known-state-file glob patterns? Probably not — too many false positives. Better: code review checklist + audit on review of any new state file.

Acceptance

  • fbuild_core::fs::write_atomic() exists with tests covering crash-mid-write recovery
  • All 5+ HIGH-risk sites migrated
  • status_manager.rs:210-225 refactored to call the shared helper (deduplication)

References: #844.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions