use std::{os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}, path::Path};
use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor};
use crate::{CDnsErrorType, CDnsResult, internal_error_map};
#[derive(Debug)]
pub struct FileNotifyDescr(WatchDescriptor);
#[derive(Debug)]
pub struct FileNotify
{
notif: Inotify,
}
impl AsFd for FileNotify
{
fn as_fd(&self) -> BorrowedFd<'_>
{
return self.notif.as_fd();
}
}
impl AsRawFd for FileNotify
{
fn as_raw_fd(&self) -> RawFd
{
return self.notif.as_fd().as_raw_fd();
}
}
impl FileNotify
{
pub
fn init() -> CDnsResult<Self>
{
let notif =
Inotify::init(InitFlags::IN_CLOEXEC | InitFlags::IN_NONBLOCK)
.map_err(|e|
internal_error_map!(CDnsErrorType::IoError, "Inotify init error '{}'", e)
)?;
return Ok(
Self{ notif: notif }
);
}
pub
fn add(&self, path: &Path) -> CDnsResult<FileNotifyDescr>
{
let wd =
self.notif.add_watch(path, AddWatchFlags::IN_MODIFY)
.map_err(|e|
internal_error_map!(CDnsErrorType::IoError, "Inotify add_watch() file: '{}' error '{}'",
path.display(), e)
)?;
return Ok(FileNotifyDescr(wd));
}
pub
fn read_events(&self) -> CDnsResult<Vec<FileNotifyDescr>>
{
return
self.notif.read_events()
.map_err(|e|
internal_error_map!(CDnsErrorType::IoError, "Inotify read_events() error '{}'",
e)
)
.map(|inf_vec|
inf_vec.into_iter().map(|inf| FileNotifyDescr(inf.wd) ).collect()
);
}
}