]> go.fuhry.dev Git - fsnotify.git/commitdiff
Linux - Fixes issue #36
authorChris Howey <chris@howey.me>
Wed, 13 Mar 2013 23:47:20 +0000 (18:47 -0500)
committerChris Howey <chris@howey.me>
Thu, 14 Mar 2013 01:15:17 +0000 (20:15 -0500)
fsnotify.go
fsnotify_linux.go

index ed731a588be09fbfc9c9e298f264bfa0482a7dfe..f371960298fbd4221425fb2240ddaef4587cce71 100644 (file)
@@ -37,13 +37,21 @@ func (w *Watcher) purgeEvents() {
                }
 
                if (fsnFlags&FSN_RENAME == FSN_RENAME) && ev.IsRename() {
-                       //w.RemoveWatch(ev.Name)
                        sendEvent = true
                }
 
                if sendEvent {
                        w.Event <- ev
                }
+
+               // If there's no file, then no more events for user
+               // BSD must keep watch for internal use (watches DELETEs to keep track
+               // what files exist for create events)
+               if ev.IsDelete() {
+                       w.fsnmut.Lock()
+                       delete(w.fsnFlags, ev.Name)
+                       w.fsnmut.Unlock()
+               }
        }
 
        close(w.Event)
index 3f0241b766bf3db1a8686c38867300f44f90017f..074ff6028cac04664e9b41835df74fbeb1b1bb81 100644 (file)
@@ -211,17 +211,17 @@ func (w *Watcher) readEvents() {
                                event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
                        }
 
-                       // Setup FSNotify flags (inherit from directory watch)
-                       w.fsnmut.Lock()
-                       fsnFlags := w.fsnFlags[watchedName]
-                       _, fsnFound := w.fsnFlags[event.Name]
-                       if !fsnFound {
-                               w.fsnFlags[event.Name] = fsnFlags
-                       }
-                       w.fsnmut.Unlock()
-
                        // Send the events that are not ignored on the events channel
-                       if (event.mask & IN_IGNORED) == 0 {
+                       if !event.ignoreLinux() {
+                               // Setup FSNotify flags (inherit from directory watch)
+                               w.fsnmut.Lock()
+                               fsnFlags := w.fsnFlags[watchedName]
+                               _, fsnFound := w.fsnFlags[event.Name]
+                               if !fsnFound {
+                                       w.fsnFlags[event.Name] = fsnFlags
+                               }
+                               w.fsnmut.Unlock()
+
                                w.internalEvent <- event
                        }
 
@@ -231,6 +231,31 @@ func (w *Watcher) readEvents() {
        }
 }
 
+// Certain types of events can be "ignored" and not sent over the Event
+// channel. Such as events marked ignore by the kernel, or MODIFY events
+// against files that do not exist.
+func (e *FileEvent) ignoreLinux() bool {
+       // Ignore anything the inotify API says to ignore
+       if e.mask&IN_IGNORED == 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.mask&IN_DELETE == IN_DELETE ||
+               e.mask&IN_DELETE_SELF == IN_DELETE_SELF ||
+               e.mask&IN_MOVED_FROM == IN_MOVED_FROM ||
+               e.mask&IN_MOVE_SELF == IN_MOVE_SELF) {
+               if _, statErr := os.Stat(e.Name); os.IsNotExist(statErr) {
+                       return true
+               }
+       }
+       return false
+}
+
 const (
        // Options for inotify_init() are not exported
        // IN_CLOEXEC    uint32 = syscall.IN_CLOEXEC