diff --git a/inotify.go b/inotify.go index c56556f4..5de38b4f 100644 --- a/inotify.go +++ b/inotify.go @@ -303,12 +303,12 @@ func (e *Event) ignoreLinux(mask uint32) bool { 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) { + // 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) } diff --git a/inotify_test.go b/inotify_test.go index 2c11d2ed..c0c6e355 100644 --- a/inotify_test.go +++ b/inotify_test.go @@ -453,3 +453,52 @@ func TestInotifyOverflow(t *testing.T) { numDirs*numFiles, creates) } } + +func TestInotifyDeleteOpenedFile(t *testing.T) { + testDir := tempMkdir(t) + defer os.RemoveAll(testDir) + + testFile := filepath.Join(testDir, "testfile") + + // create and open a file + fd, err := os.Create(testFile) + if err != nil { + t.Fatalf("Create failed: %v", err) + } + defer fd.Close() + + w, err := NewWatcher() + if err != nil { + t.Fatalf("Failed to create watcher: %v", err) + } + defer w.Close() + + err = w.Add(testFile) + if err != nil { + t.Fatalf("Failed to add watch for %s: %v", testFile, err) + } + + checkEvent := func(exp Op) { + select { + case event := <-w.Events: + t.Logf("Event received: %s", event.Op) + if event.Op != exp { + t.Fatalf("Event expected: %s, got: %s", exp, event.Op) + } + case <-time.After(100 * time.Millisecond): + t.Fatalf("Expected %s event not received", exp) + } + } + + // Remove the (opened) file, check Chmod event (notifying + // about file link count change) is received + err = os.Remove(testFile) + if err != nil { + t.Fatalf("Failed to remove file: %s", err) + } + checkEvent(Chmod) + + // Close the file, check Remove event is received + fd.Close() + checkEvent(Remove) +}