+
+#[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;
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<T: AsRef<OsStr>>(x: T) -> Vec<winapi::shared::ntdef::WCHAR> {
+ x.as_ref().encode_wide().chain(Some(0)).collect()
+}
#[allow(bare_trait_objects)]
pub(crate) fn write_to_file<D: DiskWriteable>(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.
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(())
}