Skip to content

Commit

Permalink
inotify: don't ignore events for files that don't exist
Browse files Browse the repository at this point in the history
port of fsnotify/fsnotify#470

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: howeyc/fsnotify#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.
  • Loading branch information
shogo82148 committed Mar 6, 2024
1 parent b408db8 commit f4dff12
Showing 1 changed file with 1 addition and 23 deletions.
24 changes: 1 addition & 23 deletions inotify.go
Expand Up @@ -11,7 +11,6 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -294,7 +293,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:
Expand All @@ -308,27 +307,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 not a DELETE or RENAME, the file must exist.
// Otherwise the event is ignored.
// *Note*: this was put in place because it was seen that a MODIFY
// event was sent after the DELETE. This ignores that MODIFY and
// assumes a DELETE will come or has come if the file doesn't exist.
if !(e.Op&Remove == Remove || e.Op&Rename == Rename) {
_, 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}
Expand Down

0 comments on commit f4dff12

Please sign in to comment.