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)
}
}
}
}
+
+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)
+}