From 5496ba512ffc1a573aac8b7ec69326e0a2ca08cd Mon Sep 17 00:00:00 2001 From: Amir Tuval Date: Tue, 5 Dec 2023 22:34:41 +0200 Subject: [PATCH 1/6] ignore idea files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index bf3bba40..0f341b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ tests/last-fails tests/last-run.log .cargo +.idea/ +*.iml From c7c8d0e8089b48b02769e107ff2ac9db19a5106d Mon Sep 17 00:00:00 2001 From: Amir Tuval Date: Wed, 6 Dec 2023 14:08:26 +0200 Subject: [PATCH 2/6] add fail_on_no_permissions flag to Config --- notify/src/config.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/notify/src/config.rs b/notify/src/config.rs index a588eb78..09534b50 100644 --- a/notify/src/config.rs +++ b/notify/src/config.rs @@ -42,6 +42,9 @@ pub struct Config { /// See [BackendConfig::with_compare_contents] compare_contents: bool, + + /// See [BackendConfig::with_fail_on_no_permissions] + fail_on_no_permissions: bool, } impl Config { @@ -94,6 +97,21 @@ impl Config { pub fn compare_contents(&self) -> bool { self.compare_contents } + + /// For the [INotifyWatcher](crate::INotifyWatcher) backend. + /// + /// This fail sets whether inotify should fail when the user has no permissions for a subfolder. + /// + /// On by default. + pub fn with_fail_on_no_permissions(mut self, fail_on_no_permissions: bool) -> Self { + self.fail_on_no_permissions = fail_on_no_permissions; + self + } + + /// Returns current setting + pub fn fail_on_no_permissions(&self) -> bool { + self.fail_on_no_permissions + } } impl Default for Config { @@ -101,6 +119,7 @@ impl Default for Config { Self { poll_interval: Some(Duration::from_secs(30)), compare_contents: false, + fail_on_no_permissions: true, } } } From e63a681be7851e1a9506d533b17af1f374e4fdba Mon Sep 17 00:00:00 2001 From: Amir Tuval Date: Wed, 6 Dec 2023 14:18:15 +0200 Subject: [PATCH 3/6] use flag --- notify/src/inotify.rs | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/notify/src/inotify.rs b/notify/src/inotify.rs index d8d81401..8c30774b 100644 --- a/notify/src/inotify.rs +++ b/notify/src/inotify.rs @@ -10,13 +10,13 @@ use crate::{bounded, unbounded, BoundSender, Receiver, Sender}; use inotify as inotify_sys; use inotify_sys::{EventMask, Inotify, WatchDescriptor, WatchMask}; use std::collections::HashMap; -use std::env; use std::ffi::OsStr; use std::fs::metadata; use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::thread; +use std::{env, io}; use walkdir::WalkDir; const INOTIFY: mio::Token = mio::Token(0); @@ -40,6 +40,7 @@ struct EventLoop { watches: HashMap, paths: HashMap, rename_event: Option, + fail_on_no_permissions: bool, } /// Watcher implementation based on inotify @@ -90,7 +91,11 @@ fn remove_watch_by_event( } impl EventLoop { - pub fn new(inotify: Inotify, event_handler: Box) -> Result { + pub fn new( + inotify: Inotify, + event_handler: Box, + fail_on_no_permissions: bool, + ) -> Result { let (event_loop_tx, event_loop_rx) = unbounded::(); let poll = mio::Poll::new()?; @@ -112,6 +117,7 @@ impl EventLoop { watches: HashMap::new(), paths: HashMap::new(), rename_event: None, + fail_on_no_permissions, }; Ok(event_loop) } @@ -307,9 +313,11 @@ impl EventLoop { } } None => { - log::trace!("No patch for DELETE_SELF event, may be a bug?"); + log::trace!( + "No patch for DELETE_SELF event, may be a bug?" + ); RemoveKind::Other - }, + } }; evs.push( Event::new(EventKind::Remove(remove_kind)) @@ -396,7 +404,20 @@ impl EventLoop { .into_iter() .filter_map(filter_dir) { - self.add_single_watch(entry.path().to_path_buf(), is_recursive, watch_self)?; + if let Err(e) = + self.add_single_watch(entry.path().to_path_buf(), is_recursive, watch_self) + { + match &e.kind { + ErrorKind::Io(io) if io.kind() == io::ErrorKind::PermissionDenied => { + // If this is the root folder we want to fail on permission error even if + // fail_on_permissions_for_subfolders flag is not set + if watch_self || self.fail_on_no_permissions { + return Err(e); + } + } + _ => return Err(e), + } + } watch_self = false; } @@ -514,9 +535,12 @@ fn filter_dir(e: walkdir::Result) -> Option) -> Result { + fn from_event_handler( + event_handler: Box, + fail_on_no_permissions: bool, + ) -> Result { let inotify = Inotify::init()?; - let event_loop = EventLoop::new(inotify, event_handler)?; + let event_loop = EventLoop::new(inotify, event_handler, fail_on_no_permissions)?; let channel = event_loop.event_loop_tx.clone(); let waker = event_loop.event_loop_waker.clone(); event_loop.run(); @@ -558,8 +582,8 @@ impl INotifyWatcher { impl Watcher for INotifyWatcher { /// Create a new watcher. - fn new(event_handler: F, _config: Config) -> Result { - Self::from_event_handler(Box::new(event_handler)) + fn new(event_handler: F, config: Config) -> Result { + Self::from_event_handler(Box::new(event_handler), config.fail_on_no_permissions()) } fn watch(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()> { From 6b22759503b631e670db9888cd3a0ecc5a91cdaa Mon Sep 17 00:00:00 2001 From: Amir Tuval Date: Wed, 6 Dec 2023 14:32:55 +0200 Subject: [PATCH 4/6] typo --- notify/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/src/config.rs b/notify/src/config.rs index 09534b50..d9204077 100644 --- a/notify/src/config.rs +++ b/notify/src/config.rs @@ -100,7 +100,7 @@ impl Config { /// For the [INotifyWatcher](crate::INotifyWatcher) backend. /// - /// This fail sets whether inotify should fail when the user has no permissions for a subfolder. + /// This flag sets whether inotify should fail when the user has no permissions for a subfolder. /// /// On by default. pub fn with_fail_on_no_permissions(mut self, fail_on_no_permissions: bool) -> Self { From d90f552f4b0cb54ae73c8fa88e4f34aab4fa5333 Mon Sep 17 00:00:00 2001 From: Amir Tuval Date: Wed, 6 Dec 2023 14:33:48 +0200 Subject: [PATCH 5/6] wording --- notify/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/src/config.rs b/notify/src/config.rs index d9204077..e64f2df6 100644 --- a/notify/src/config.rs +++ b/notify/src/config.rs @@ -100,7 +100,7 @@ impl Config { /// For the [INotifyWatcher](crate::INotifyWatcher) backend. /// - /// This flag sets whether inotify should fail when the user has no permissions for a subfolder. + /// This flag sets whether inotify should fail when the user has no permissions on a subfolder. /// /// On by default. pub fn with_fail_on_no_permissions(mut self, fail_on_no_permissions: bool) -> Self { From e315d15781105ac166303380b5955aee3f733300 Mon Sep 17 00:00:00 2001 From: amircodota <25413470+amircodota@users.noreply.github.com> Date: Fri, 21 Jun 2024 21:51:16 +0300 Subject: [PATCH 6/6] Fix an "illegal instruction" crash on windows. See more details here - https://github.com/rust-lang/rust/issues/126195 --- notify/src/windows.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notify/src/windows.rs b/notify/src/windows.rs index 65c85147..1e2d2884 100644 --- a/notify/src/windows.rs +++ b/notify/src/windows.rs @@ -282,8 +282,8 @@ fn start_read(rd: &ReadData, event_handler: Arc>, handle // for our own purposes let req_buf = request.buffer.as_mut_ptr() as *mut c_void; - let request_p = Box::into_raw(request) as isize; - overlapped.hEvent = request_p; + let request_p = Box::into_raw(request); + overlapped.hEvent = request_p as isize; // This is using an asynchronous call with a completion routine for receiving notifications // An I/O completion port would probably be more performant @@ -304,7 +304,7 @@ fn start_read(rd: &ReadData, event_handler: Arc>, handle // over to `ReadDirectoryChangesW`. // So we can claim ownership back. let _overlapped_alloc = std::mem::ManuallyDrop::into_inner(overlapped); - let request: Box = mem::transmute(request_p); + let request: Box = Box::from_raw(request_p); ReleaseSemaphore(request.data.complete_sem, 1, ptr::null_mut()); } }