#![allow(unsafe_code)]
use std::fs::File;
use std::path::Path;
use anyhow::{Context, Result};
pub fn fsync_file(file: &File) -> Result<()> {
#[cfg(target_os = "macos")]
{
use std::os::unix::io::AsRawFd;
let fd = file.as_raw_fd();
let ret = unsafe { libc::fcntl(fd, libc::F_FULLFSYNC) };
if ret == -1 {
file.sync_data()
.context("fsync fallback after F_FULLFSYNC failure")?;
}
return Ok(());
}
#[cfg(not(target_os = "macos"))]
{
file.sync_data().context("fsync file")?;
Ok(())
}
}
pub fn fsync_dir(dir: &Path) -> Result<()> {
#[cfg(unix)]
{
let file = File::open(dir)
.with_context(|| format!("cannot open directory {} for fsync", dir.display()))?;
file.sync_all()
.with_context(|| format!("fsync directory {}", dir.display()))?;
Ok(())
}
#[cfg(windows)]
{
let _ = dir;
Ok(())
}
#[cfg(not(any(unix, windows)))]
{
let _ = dir;
Ok(())
}
}
pub fn preserve_timestamps(
path: &Path,
mtime: filetime::FileTime,
atime: filetime::FileTime,
) -> Result<()> {
filetime::set_file_times(path, atime, mtime)
.with_context(|| format!("cannot restore timestamps on {}", path.display()))
}
pub fn platform_fsync_name() -> &'static str {
#[cfg(target_os = "macos")]
{
"F_FULLFSYNC"
}
#[cfg(not(target_os = "macos"))]
{
"sync_data"
}
}
#[cfg(windows)]
pub fn init_console() {
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
use windows_sys::Win32::System::Console::*;
unsafe {
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
for handle_id in [STD_OUTPUT_HANDLE, STD_ERROR_HANDLE] {
let handle = GetStdHandle(handle_id);
if handle != 0 && handle != INVALID_HANDLE_VALUE {
let mut mode: u32 = 0;
if GetConsoleMode(handle, &mut mode) != 0 {
let _ = SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
}
}
}
}
#[cfg(not(windows))]
pub fn init_console() {}
pub fn platform_dir_fsync_name() -> &'static str {
#[cfg(unix)]
{
"sync_all"
}
#[cfg(windows)]
{
"best_effort"
}
#[cfg(not(any(unix, windows)))]
{
"none"
}
}