@@ -73,8 +73,6 @@ type Listener struct {
7373 fd int
7474 // flags passed to fanotify_init
7575 flags uint
76- // markMask current fanotify mark mask
77- markMask uint64
7876 // mount fd is the file descriptor of the mountpoint
7977 mountpoint * os.File
8078 kernelMajorVersion int
@@ -205,23 +203,14 @@ func (l *Listener) Stop() {
205203// for - [FileCreated], [FileAttribChanged], [FileMovedTo], [FileMovedFrom], [WatchedFileDeleted],
206204// [WatchedFileOrDirectoryDeleted], [FileDeleted], [FileOrDirectoryDeleted]
207205func (l * Listener ) WatchMount (eventTypes EventType ) error {
208- mask := l .getMaskAfterAdd (eventTypes )
209- l .clearWatch ()
210- l .markMask = uint64 (mask )
211- return l .fanotifyMark (l .mountpoint .Name (), unix .FAN_MARK_ADD | unix .FAN_MARK_MOUNT , uint64 (mask ))
206+ return l .fanotifyMark (l .mountpoint .Name (), unix .FAN_MARK_ADD | unix .FAN_MARK_MOUNT , uint64 (eventTypes ))
212207}
213208
214209// UnwatchMount removes the notification marks for the entire mount point.
215210// This method returns an [ErrWatchPath] if the listener was not initialized to monitor
216211// the entire mount point. To unmark specific files or directories use [DeleteWatch] method.
217212func (l * Listener ) UnwatchMount (eventTypes EventType ) error {
218- if l .markMask == 0 {
219- return l .clearWatch ()
220- }
221- remaining := l .getMaskAfterRemove (eventTypes )
222- l .clearWatch ()
223- l .markMask = uint64 (remaining )
224- return l .fanotifyMark (l .mountpoint .Name (), unix .FAN_MARK_ADD | unix .FAN_MARK_MOUNT , uint64 (remaining ))
213+ return l .fanotifyMark (l .mountpoint .Name (), unix .FAN_MARK_REMOVE | unix .FAN_MARK_MOUNT , uint64 (eventTypes ))
225214}
226215
227216// AddWatch adds or modifies the fanotify mark for the specified path.
@@ -232,46 +221,14 @@ func (l *Listener) UnwatchMount(eventTypes EventType) error {
232221// - [FileCreated] cannot be or-ed / combined with [FileClosed]. The fanotify system does not generate any event for this combination.
233222// - [FileOpened] with any of the event types containing OrDirectory causes an event flood for the directory and then stopping raising any events at all.
234223// - [FileOrDirectoryOpened] with any of the other event types causes an event flood for the directory and then stopping raising any events at all.
235- //
236- // NOTE:
237- // Any event type that contains "OrDirectory" applies the OrDirectory mask to any other applicable
238- // marks. For example adding [FileDeleted] and [FileOrDirectoryOpened] will apply "OrDirectory" to
239- // [FileDeleted] thus the resulting mask will be set to [FileOrDirectoryOpened] and [FileOrDirectoryDeleted]
240224func (l * Listener ) AddWatch (path string , eventTypes EventType ) error {
241225 if l == nil {
242226 panic ("nil listener" )
243227 }
244228 if l .entireMount {
245229 return os .ErrInvalid
246230 }
247- mask := l .getMaskAfterAdd (eventTypes )
248- l .clearWatch ()
249- l .markMask = uint64 (mask )
250- return l .fanotifyMark (path , unix .FAN_MARK_ADD , uint64 (mask | unix .FAN_EVENT_ON_CHILD ))
251- }
252-
253- // DeleteWatch removes/unmarks the fanotify mark for the specified path.
254- // Calling DeleteWatch on the listener initialized to monitor the entire mount point
255- // results in [os.ErrInvalid]. Use [UnwatchMount] for deleting marks on the mount point.
256- func (l * Listener ) DeleteWatch (parentDir string , eventTypes EventType ) error {
257- if l .entireMount {
258- return os .ErrInvalid
259- }
260- if l .markMask == 0 {
261- return l .clearWatch ()
262- }
263- remaining := l .getMaskAfterRemove (eventTypes )
264- l .clearWatch ()
265- l .markMask = uint64 (remaining )
266- return l .fanotifyMark (parentDir , unix .FAN_MARK_ADD , uint64 (remaining | unix .FAN_EVENT_ON_CHILD ))
267- }
268-
269- // ClearWatch stops watching for all event types
270- func (l * Listener ) ClearWatch () error {
271- if l == nil {
272- panic ("nil listener" )
273- }
274- return l .clearWatch ()
231+ return l .fanotifyMark (path , unix .FAN_MARK_ADD , uint64 (eventTypes | unix .FAN_EVENT_ON_CHILD ))
275232}
276233
277234// Allow sends an "allowed" response to the permission request event.
@@ -294,6 +251,28 @@ func (l *Listener) Deny(e Event) {
294251 unix .Write (l .fd , buf .Bytes ())
295252}
296253
254+ // DeleteWatch removes/unmarks the fanotify mark for the specified path.
255+ // Calling DeleteWatch on the listener initialized to monitor the entire mount point
256+ // results in [os.ErrInvalid]. Use [UnwatchMount] for deleting marks on the mount point.
257+ func (l * Listener ) DeleteWatch (parentDir string , eventTypes EventType ) error {
258+ if l .entireMount {
259+ return os .ErrInvalid
260+ }
261+ return l .fanotifyMark (parentDir , unix .FAN_MARK_REMOVE , uint64 (eventTypes | unix .FAN_EVENT_ON_CHILD ))
262+ }
263+
264+ // ClearWatch stops watching for all event types
265+ func (l * Listener ) ClearWatch () error {
266+ if l == nil {
267+ panic ("nil listener" )
268+ }
269+ if err := unix .FanotifyMark (l .fd , unix .FAN_MARK_FLUSH , 0 , - 1 , "" ); err != nil {
270+ return err
271+ }
272+ l .watches = make (map [string ]bool )
273+ return nil
274+ }
275+
297276// Has returns true if event types (e) contains the passed in event type (et).
298277func (e EventType ) Has (et EventType ) bool {
299278 return e & et == et
0 commit comments