use std::fs::File;
use std::io::{self, Seek, SeekFrom};
use std::time::Duration;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use mio;
use mio::unix::{EventedFd, UnixReady};
use nix::poll::{self, PollFd, EventFlags};
use libc::c_int;
use super::*;
use inotify;
use logger;
pub struct FileWatcher {
inotify: inotify::Inotify,
poll: mio::Poll,
events: mio::Events,
}
impl FileWatcher {
pub fn new(file_path: &str) -> io::Result<Self> {
let mut inotify = inotify::Inotify::init()?;
inotify.add_watch(file_path, inotify::WatchMask::MODIFY)?;
let poll = mio::Poll::new()?;
let events = mio::Events::with_capacity(1024);
logger::log(&format!("ino:fd={}", inotify.as_raw_fd()));
poll.register(
&EventedFd(&inotify.as_raw_fd()),
mio::Token(0),
mio::Ready::readable(),
mio::PollOpt::edge(),
).unwrap();
Ok( Self { inotify, poll, events } )
}
}
impl FileWatch for FileWatcher {
fn block(&mut self, timeout: Option<Duration>) -> io::Result<Option<bool>> {
self.poll.poll(&mut self.events, timeout)?;
Ok(
if self.events.is_empty() {
logger::log("inotify:timeout");
None
} else {
static token_id: usize = 0;
let evt = &self.events.iter().next();
let mut buf = [0u8; 1024];
self.inotify.read_events(&mut buf)?;
// self.poll.register(
// &EventedFd(&self.inotify.as_raw_fd()),
// mio::Token(if token_id == 0 { 1 } else { 0 }),
// mio::Ready::readable(),
// mio::PollOpt::edge(),
// ).unwrap();
if let Some(e) = evt {
logger::log("inotify:some");
Some(UnixReady::from(e.readiness()).is_hup())
} else {
logger::log("inotify:none");
None
}
}
)
}
}
pub struct StdinWatcher {
poll: mio::Poll,
events: mio::Events,
}
impl StdinWatcher {
pub fn new(fd: RawFd) -> io::Result<Self> {
let poll = mio::Poll::new()?;
let events = mio::Events::with_capacity(1024);
poll.register(
&EventedFd(&fd),
mio::Token(0),
mio::Ready::readable(),
mio::PollOpt::edge(),
)?;
Ok( Self{ poll, events } )
}
}
impl FileWatch for StdinWatcher {
fn block(&mut self, timeout: Option<Duration>) -> io::Result<Option<bool>> {
self.poll.poll(&mut self.events, timeout)?;
Ok(
if self.events.is_empty() {
None
} else {
let evt = &self.events.iter().next();
if let Some(e) = evt {
Some(UnixReady::from(e.readiness()).is_hup())
} else {
None
}
}
)
}
}