Skip to content

Commit

Permalink
Fixed the Event of watch dir Deletion (#540)
Browse files Browse the repository at this point in the history
* bugfix:493_watched_dir_status_File

* refactoring

* refactors

* Update notify/src/inotify.rs

Co-authored-by: Aron <Ox0p54r36@t-online.de>

* refactor: Removed unwrap call

* Removed the extra comment before doc comment.

* remove unnecessary clone

* warn on missing path for DELETE_SELF

---------

Co-authored-by: Aron <Ox0p54r36@t-online.de>
  • Loading branch information
zeroishero and 0xpr03 authored Nov 1, 2023
1 parent 146790b commit c4d0470
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions notify/src/inotify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const MESSAGE: mio::Token = mio::Token(1);
// - messages telling it what to do
//
// - events telling it that something has happened on one of the watched files.

struct EventLoop {
running: bool,
poll: mio::Poll,
Expand All @@ -35,7 +36,8 @@ struct EventLoop {
event_loop_rx: Receiver<EventLoopMsg>,
inotify: Option<Inotify>,
event_handler: Box<dyn EventHandler>,
watches: HashMap<PathBuf, (WatchDescriptor, WatchMask, bool)>,
/// PathBuf -> (WatchDescriptor, WatchMask, is_recursive, is_dir)
watches: HashMap<PathBuf, (WatchDescriptor, WatchMask, bool, bool)>,
paths: HashMap<WatchDescriptor, PathBuf>,
rename_event: Option<Event>,
}
Expand All @@ -58,13 +60,13 @@ enum EventLoopMsg {
fn add_watch_by_event(
path: &Option<PathBuf>,
event: &inotify_sys::Event<&OsStr>,
watches: &HashMap<PathBuf, (WatchDescriptor, WatchMask, bool)>,
watches: &HashMap<PathBuf, (WatchDescriptor, WatchMask, bool, bool)>,
add_watches: &mut Vec<PathBuf>,
) {
if let Some(ref path) = *path {
if event.mask.contains(EventMask::ISDIR) {
if let Some(parent_path) = path.parent() {
if let Some(&(_, _, is_recursive)) = watches.get(parent_path) {
if let Some(&(_, _, is_recursive, _)) = watches.get(parent_path) {
if is_recursive {
add_watches.push(path.to_owned());
}
Expand All @@ -77,7 +79,7 @@ fn add_watch_by_event(
#[inline]
fn remove_watch_by_event(
path: &Option<PathBuf>,
watches: &HashMap<PathBuf, (WatchDescriptor, WatchMask, bool)>,
watches: &HashMap<PathBuf, (WatchDescriptor, WatchMask, bool, bool)>,
remove_watches: &mut Vec<PathBuf>,
) {
if let Some(ref path) = *path {
Expand Down Expand Up @@ -281,9 +283,7 @@ impl EventLoop {
);
add_watch_by_event(&path, &event, &self.watches, &mut add_watches);
}
if event.mask.contains(EventMask::DELETE_SELF)
|| event.mask.contains(EventMask::DELETE)
{
if event.mask.contains(EventMask::DELETE) {
evs.push(
Event::new(EventKind::Remove(
if event.mask.contains(EventMask::ISDIR) {
Expand All @@ -296,6 +296,27 @@ impl EventLoop {
);
remove_watch_by_event(&path, &self.watches, &mut remove_watches);
}
if event.mask.contains(EventMask::DELETE_SELF) {
let remove_kind = match &path {
Some(watched_path) => {
let current_watch = self.watches.get(watched_path);
match current_watch {
Some(&(_, _, _, true)) => RemoveKind::Folder,
Some(&(_, _, _, false)) => RemoveKind::File,
None => RemoveKind::Other,
}
}
None => {
log::trace!("No patch for DELETE_SELF event, may be a bug?");
RemoveKind::Other
},
};
evs.push(
Event::new(EventKind::Remove(remove_kind))
.add_some_path(path.clone()),
);
remove_watch_by_event(&path, &self.watches, &mut remove_watches);
}
if event.mask.contains(EventMask::MODIFY) {
evs.push(
Event::new(EventKind::Modify(ModifyKind::Data(
Expand Down Expand Up @@ -401,7 +422,7 @@ impl EventLoop {
watchmask.insert(WatchMask::MOVE_SELF);
}

if let Some(&(_, old_watchmask, _)) = self.watches.get(&path) {
if let Some(&(_, old_watchmask, _, _)) = self.watches.get(&path) {
watchmask.insert(old_watchmask);
watchmask.insert(WatchMask::MASK_ADD);
}
Expand All @@ -421,8 +442,9 @@ impl EventLoop {
}
Ok(w) => {
watchmask.remove(WatchMask::MASK_ADD);
let is_dir = metadata(&path).map_err(Error::io)?.is_dir();
self.watches
.insert(path.clone(), (w.clone(), watchmask, is_recursive));
.insert(path.clone(), (w.clone(), watchmask, is_recursive, is_dir));
self.paths.insert(w, path);
Ok(())
}
Expand All @@ -435,7 +457,7 @@ impl EventLoop {
fn remove_watch(&mut self, path: PathBuf, remove_recursive: bool) -> Result<()> {
match self.watches.remove(&path) {
None => return Err(Error::watch_not_found().add_path(path)),
Some((w, _, is_recursive)) => {
Some((w, _, is_recursive, _)) => {
if let Some(ref mut inotify) = self.inotify {
log::trace!("removing inotify watch: {}", path.display());

Expand Down

0 comments on commit c4d0470

Please sign in to comment.