use std::io::Write;
use std::path::{Path, PathBuf};
use crate::{Result, SalamanderError};
const LOCK_FILE_NAME: &str = "LOCK";
pub(crate) struct DirLock {
path: PathBuf,
}
impl DirLock {
pub(crate) fn acquire(dir: &Path) -> Result<Self> {
let path = dir.join(LOCK_FILE_NAME);
match std::fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(&path)
{
Ok(mut file) => {
let _ = writeln!(file, "{}", std::process::id());
Ok(DirLock { path })
}
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {
Err(SalamanderError::Locked(format!(
"{} exists; another process may hold this data dir. If no \
process is using it, delete the LOCK file and retry.",
path.display()
)))
}
Err(e) => Err(SalamanderError::Io(e)),
}
}
}
impl Drop for DirLock {
fn drop(&mut self) {
let _ = std::fs::remove_file(&self.path);
}
}