From b1112f85525bdef8569b5502770abdb10746e1a7 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sun, 24 Jul 2022 12:56:22 +0200 Subject: [PATCH] inotify: don't ignore events for files that don't exist This is quite an odd check, leading to an inconsistent event stream, which also doesn't match what other platforms do. If you do a "CREATE + MODIFY + REMOVE" in quick succession then you probably *want* all three events. If you don't want to operate on non-existing files, then you can check this in your application code. You need to do that already, since this check is far from reliable. In the time between this check and the application code doing something with an event the file may have been deleted already. I looked a bit at the history of this, and looks like it was added in 2013 with cc2c34e; issue 36 refers to this issue on the old repo, which mentions it fixes a memory leak: https://github.com/howeyc/fsnotify/issues/36 I can't reproduce that at all; using the CLI from #463 modified to print the memory and running: for i in $(seq 0 10000); { touch $i; rm $i } Memory stays at about 100/110K in both the current main branch and this. So I think it should be safe to remove. --- inotify.go | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/inotify.go b/inotify.go index a42da583..71254996 100644 --- a/inotify.go +++ b/inotify.go @@ -279,7 +279,7 @@ func (w *Watcher) readEvents() { event := newEvent(name, mask) // Send the events that are not ignored on the events channel - if !event.ignoreLinux(mask) { + if mask&unix.IN_IGNORED == 0 { select { case w.Events <- event: case <-w.done: @@ -293,27 +293,6 @@ func (w *Watcher) readEvents() { } } -// Certain types of events can be "ignored" and not sent over the Events -// channel. Such as events marked ignore by the kernel, or MODIFY events -// against files that do not exist. -func (e *Event) ignoreLinux(mask uint32) bool { - // Ignore anything the inotify API says to ignore - if mask&unix.IN_IGNORED == unix.IN_IGNORED { - return true - } - - // If the event is Create or Write, the file must exist, or the - // event will be suppressed. - // *Note*: this was put in place because it was seen that a Write - // event was sent after the Remove. This ignores the Write and - // assumes a Remove will come or has come if the file doesn't exist. - if e.Op&Create == Create || e.Op&Write == Write { - _, statErr := os.Lstat(e.Name) - return os.IsNotExist(statErr) - } - return false -} - // newEvent returns an platform-independent Event based on an inotify mask. func newEvent(name string, mask uint32) Event { e := Event{Name: name}