diff options
Diffstat (limited to 'Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go')
-rw-r--r-- | Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go index 265622d20..9662a50a8 100644 --- a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go +++ b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/kqueue.go @@ -94,7 +94,8 @@ func (w *Watcher) Add(name string) error { w.mu.Lock() w.externalWatches[name] = true w.mu.Unlock() - return w.addWatch(name, noteAllEvents) + _, err := w.addWatch(name, noteAllEvents) + return err } // Remove stops watching the the named file or directory (non-recursively). @@ -153,7 +154,8 @@ var keventWaitTime = durationToTimespec(100 * time.Millisecond) // addWatch adds name to the watched file set. // The flags are interpreted as described in kevent(2). -func (w *Watcher) addWatch(name string, flags uint32) error { +// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks. +func (w *Watcher) addWatch(name string, flags uint32) (string, error) { var isDir bool // Make ./name and name equivalent name = filepath.Clean(name) @@ -161,7 +163,7 @@ func (w *Watcher) addWatch(name string, flags uint32) error { w.mu.Lock() if w.isClosed { w.mu.Unlock() - return errors.New("kevent instance already closed") + return "", errors.New("kevent instance already closed") } watchfd, alreadyWatching := w.watches[name] // We already have a watch, but we can still override flags. @@ -173,12 +175,17 @@ func (w *Watcher) addWatch(name string, flags uint32) error { if !alreadyWatching { fi, err := os.Lstat(name) if err != nil { - return err + return "", err } // Don't watch sockets. if fi.Mode()&os.ModeSocket == os.ModeSocket { - return nil + return "", nil + } + + // Don't watch named pipes. + if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe { + return "", nil } // Follow Symlinks @@ -190,18 +197,26 @@ func (w *Watcher) addWatch(name string, flags uint32) error { if fi.Mode()&os.ModeSymlink == os.ModeSymlink { name, err = filepath.EvalSymlinks(name) if err != nil { - return nil + return "", nil + } + + w.mu.Lock() + _, alreadyWatching = w.watches[name] + w.mu.Unlock() + + if alreadyWatching { + return name, nil } fi, err = os.Lstat(name) if err != nil { - return nil + return "", nil } } watchfd, err = syscall.Open(name, openMode, 0700) if watchfd == -1 { - return err + return "", err } isDir = fi.IsDir() @@ -210,7 +225,7 @@ func (w *Watcher) addWatch(name string, flags uint32) error { const registerAdd = syscall.EV_ADD | syscall.EV_CLEAR | syscall.EV_ENABLE if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil { syscall.Close(watchfd) - return err + return "", err } if !alreadyWatching { @@ -224,6 +239,7 @@ func (w *Watcher) addWatch(name string, flags uint32) error { // Watch the directory if it has not been watched before, // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) w.mu.Lock() + watchDir := (flags&syscall.NOTE_WRITE) == syscall.NOTE_WRITE && (!alreadyWatching || (w.dirFlags[name]&syscall.NOTE_WRITE) != syscall.NOTE_WRITE) // Store flags so this watch can be updated later @@ -232,11 +248,11 @@ func (w *Watcher) addWatch(name string, flags uint32) error { if watchDir { if err := w.watchDirectoryFiles(name); err != nil { - return err + return "", err } } } - return nil + return name, nil } // readEvents reads from kqueue and converts the received kevents into @@ -359,7 +375,8 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error { for _, fileInfo := range files { filePath := filepath.Join(dirPath, fileInfo.Name()) - if err := w.internalWatch(filePath, fileInfo); err != nil { + filePath, err = w.internalWatch(filePath, fileInfo) + if err != nil { return err } @@ -394,7 +411,8 @@ func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { } // like watchDirectoryFiles (but without doing another ReadDir) - if err := w.internalWatch(filePath, fileInfo); err != nil { + filePath, err = w.internalWatch(filePath, fileInfo) + if err != nil { return } @@ -404,7 +422,7 @@ func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { } } -func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) error { +func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) { if fileInfo.IsDir() { // mimic Linux providing delete events for subdirectories // but preserve the flags used if currently watching subdirectory @@ -412,7 +430,7 @@ func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) error { flags := w.dirFlags[name] w.mu.Unlock() - flags |= syscall.NOTE_DELETE + flags |= syscall.NOTE_DELETE | syscall.NOTE_RENAME return w.addWatch(name, flags) } |