From 7c44dcd682892f682bc5c98ed40c0fe1606de087 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Tue, 16 Feb 2021 20:22:53 -0500 Subject: [PATCH] trying atomic rename thing --- lightning-persister/Cargo.toml | 3 +++ lightning-persister/src/util.rs | 47 ++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lightning-persister/Cargo.toml b/lightning-persister/Cargo.toml index 63b69a1e1..a6c464554 100644 --- a/lightning-persister/Cargo.toml +++ b/lightning-persister/Cargo.toml @@ -16,5 +16,8 @@ libc = "0.2" version = "0.24" features = ["bitcoinconsensus"] +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["winbase"] } + [dev-dependencies] lightning = { version = "0.0.12", path = "../lightning", features = ["_test_utils"] } diff --git a/lightning-persister/src/util.rs b/lightning-persister/src/util.rs index 004bc5d67..7d63a4156 100644 --- a/lightning-persister/src/util.rs +++ b/lightning-persister/src/util.rs @@ -1,6 +1,14 @@ + +#[cfg(target_os = "windows")] +extern crate winapi; + use std::fs; use std::path::{Path, PathBuf}; - +#[cfg(target_os = "windows")] + use { + std::ffi::OsStr, + std::os::windows::ffi::OsStrExt + }; #[cfg(not(target_os = "windows"))] use std::os::unix::io::AsRawFd; @@ -13,12 +21,34 @@ pub(crate) fn get_full_filepath(filepath: String, filename: String) -> String { path.push(filename); path.to_str().unwrap().to_string() } +#[cfg(target_os = "windows")] +macro_rules! call { + ($e: expr) => ( + if $e != 0 { + return Ok(()) + } else { + return Err(std::io::Error::last_os_error()) + } + ) +} + +#[cfg(target_os = "windows")] +fn path_to_windows_str>(x: T) -> Vec { + x.as_ref().encode_wide().chain(Some(0)).collect() +} #[allow(bare_trait_objects)] pub(crate) fn write_to_file(path: String, filename: String, data: &D) -> std::io::Result<()> { println!("VMW: creating dir"); fs::create_dir_all(path.clone())?; println!("VMW: created dir"); + + println!("VMW: entries in dir:"); + let dir = PathBuf::from(path.clone()); + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap(); + println!("VMW: entry in dir: {:?}", entry.path()); + } // Do a crazy dance with lots of fsync()s to be overly cautious here... // We never want to end up in a state where we've lost the old data, or end up using the // old data on power loss after we've returned. @@ -38,16 +68,25 @@ pub(crate) fn write_to_file(path: String, filename: String, da f.sync_all()?; println!("VMW: sync'd all"); } - println!("VMW: about to rename"); - fs::rename(&tmp_filename, &filename_with_path)?; - println!("VMW: renamed"); // Fsync the parent directory on Unix. #[cfg(not(target_os = "windows"))] { + fs::rename(&tmp_filename, &filename_with_path)?; let path = Path::new(&filename_with_path).parent().unwrap(); let dir_file = fs::OpenOptions::new().read(true).open(path)?; unsafe { libc::fsync(dir_file.as_raw_fd()); } } + #[cfg(target_os = "windows")] + { + println!("VMW: about to rename"); + let src = PathBuf::from(tmp_filename); + let dst = PathBuf::from(filename_with_path); + call!(unsafe {winapi::um::winbase::MoveFileExW( + path_to_windows_str(src).as_ptr(), path_to_windows_str(dst).as_ptr(), + winapi::um::winbase::MOVEFILE_WRITE_THROUGH | winapi::um::winbase::MOVEFILE_REPLACE_EXISTING + )}); + println!("VMW: renamed"); + } Ok(()) } -- 2.39.5