Newer
Older
use core::ops::{Deref, DerefMut};
#[cfg(feature = "fs_locks")]
use fs4::FileExt;
use std::{
fs::{File as StdFile, OpenOptions},
path::Path,
thread::panicking,
};
pub fn open_rwlocked<P: AsRef<Path>>(path: P) -> IoResult<File> {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
// truncate as needed during store_to_disk
//.truncate(truncate)
.open(path)?;
//println!("File::open_rwlocked(... {:?}) at {}",path.file_name(),file.stream_position()?);
#[cfg(feature = "fs_locks")]
{
file.lock_exclusive()?;
}
Ok(File(file))
}
pub struct File(StdFile);
impl Drop for File {
fn drop(&mut self) {
if let Err(e) = self.0.flush().and_then(|_| self.0.unlock()) {
let error = format!(
"unable to flush and unlock multi_key_manager::File: {:?}",
e
);
if panicking() {
eprintln!("{error}");
} else {
panic!("{error}");
}
};
}
}
impl File {
pub fn empty(&self) -> IoResult<bool> {
Ok(self.0.metadata()?.len() == 0)
}
}
impl Deref for File {
type Target = StdFile;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for File {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl std::fmt::Debug for File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("File").finish()
}
}
/*
#[cfg(unix)]
use std::os::unix::prelude::OpenOptionsExt;
pub fn open_rwlocked<P: AsRef<Path>>(path: P) -> IoResult<File> {
let path = path.as_ref();
let mut file = OpenOptions::new();
file.write(true).create(true).truncate(true);
#[cfg(unix)]
{
file.custom_flags(libc::F_LOCK | libc::O_DSYNC);
}
#[cfg(windows)]
{
file.share_mode(winapi);
}
file.open(path)
//?;
}
*/