A file-based task manager
1use crate::errors::{Error, Result}; 2use std::fs; 3use std::os::unix::fs::MetadataExt; 4use std::{ 5 fs::{File, OpenOptions}, 6 path::{Path, PathBuf}, 7}; 8 9use nix::fcntl::{Flock, FlockArg}; 10 11pub fn flopen(path: PathBuf, mode: FlockArg) -> Result<Flock<File>> { 12 let file = OpenOptions::new() 13 .read(true) 14 .write(true) 15 .create(true) 16 .truncate(false) 17 .open(path)?; 18 Flock::lock(file, mode).map_err(|(_, errno)| Error::Lock(errno)) 19} 20 21/// Recursively searches upwards for a directory 22pub fn find_parent_with_dir( 23 dir: PathBuf, 24 searching_for: impl AsRef<Path>, 25) -> Result<Option<PathBuf>> { 26 // Create a new pathbuf to modify, we slap a segment onto the end but then pop it off right 27 // away 28 let mut d = dir.join(&searching_for); 29 while d.pop() { 30 let check = d.join(&searching_for); 31 if check.exists() { 32 if fs::metadata(&check)?.dev() != fs::metadata(&dir)?.dev() { 33 // we hit a filesystem boundary 34 return Ok(None); 35 } 36 return Ok(Some(check)); 37 } 38 } 39 Ok(None) 40}