Assumption: path inside cache directory. Then, we don't have to use sound OS-specific exclusive file access. Note: there's no need to remove temporary file here - cleanup task will do it later.
(path: &Path, reason: &str, contents: &[u8])
| 322 | // Then, we don't have to use sound OS-specific exclusive file access. |
| 323 | // Note: there's no need to remove temporary file here - cleanup task will do it later. |
| 324 | fn fs_write_atomic(path: &Path, reason: &str, contents: &[u8]) -> io::Result<()> { |
| 325 | let lock_path = path.with_extension(format!("wip-atomic-write-{reason}")); |
| 326 | fs::OpenOptions::new() |
| 327 | .create_new(true) // atomic file creation (assumption: no one will open it without this flag) |
| 328 | .write(true) |
| 329 | .open(&lock_path) |
| 330 | .and_then(|mut file| file.write_all(contents)) |
| 331 | // file should go out of scope and be closed at this point |
| 332 | .and_then(|()| fs::rename(&lock_path, &path)) // atomic file rename |
| 333 | } |
| 334 | |
| 335 | #[cfg(test)] |
| 336 | mod tests; |