瀏覽代碼

Merge pull request #22088 from amitkris/update_fsnotify

Update fsnotify to v1.2.11
Alexander Morozov 9 年之前
父節點
當前提交
2b6d7f728e

+ 1 - 1
hack/vendor.sh

@@ -78,7 +78,7 @@ clone git github.com/philhofer/fwd 899e4efba8eaa1fea74175308f3fae18ff3319fa
 clone git github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
 
 # fsnotify
-clone git gopkg.in/fsnotify.v1 v1.2.0
+clone git gopkg.in/fsnotify.v1 v1.2.11
 
 # awslogs deps
 clone git github.com/aws/aws-sdk-go v0.9.9

+ 16 - 2
vendor/src/gopkg.in/fsnotify.v1/.travis.yml

@@ -2,10 +2,24 @@ sudo: false
 language: go
 
 go:
-  - 1.4.1
+  - 1.5.4
+  - 1.6.1
+  - tip
+
+matrix:
+  allow_failures:
+    - go: tip
 
 before_script:
-  - FIXED=$(go fmt ./... | wc -l); if [ $FIXED -gt 0 ]; then echo "gofmt - $FIXED file(s) not formatted correctly, please run gofmt to fix this." && exit 1; fi
+  - go get -u github.com/golang/lint/golint
+
+script:
+  - go test -v --race ./...
+
+after_script:
+  - test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
+  - test -z "$(golint ./...     | tee /dev/stderr)"
+  - go vet ./...
 
 os:
   - linux

+ 10 - 1
vendor/src/gopkg.in/fsnotify.v1/AUTHORS

@@ -9,22 +9,30 @@
 # Please keep the list sorted.
 
 Adrien Bustany <adrien@bustany.org>
+Amit Krishnan <amit.krishnan@oracle.com>
+Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
 Caleb Spare <cespare@gmail.com>
 Case Nelson <case@teammating.com>
-Chris Howey <howeyc@gmail.com> <chris@howey.me>
+Chris Howey <chris@howey.me> <howeyc@gmail.com>
 Christoffer Buchholz <christoffer.buchholz@gmail.com>
+Daniel Wagner-Hall <dawagner@gmail.com>
 Dave Cheney <dave@cheney.net>
+Evan Phoenix <evan@fallingsnow.net>
 Francisco Souza <f@souza.cc>
 Hari haran <hariharan.uno@gmail.com>
 John C Barstow
 Kelvin Fo <vmirage@gmail.com>
+Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
 Matt Layher <mdlayher@gmail.com>
 Nathan Youngman <git@nathany.com>
 Paul Hammond <paul@paulhammond.org>
+Pawel Knap <pawelknap88@gmail.com>
 Pieter Droogendijk <pieter@binky.org.uk>
 Pursuit92 <JoshChase@techpursuit.net>
+Riku Voipio <riku.voipio@linaro.org>
 Rob Figueiredo <robfig@gmail.com>
 Soge Zhang <zhssoge@gmail.com>
+Tiffany Jernigan <tiffany.jernigan@intel.com>
 Tilak Sharma <tilaks@google.com>
 Travis Cline <travis.cline@gmail.com>
 Tudor Golubenco <tudor.g@gmail.com>
@@ -32,3 +40,4 @@ Yukang <moorekang@gmail.com>
 bronze1man <bronze1man@gmail.com>
 debrando <denis.brandolini@gmail.com>
 henrikedwards <henrik.edwards@gmail.com>
+铁哥 <guotie.9@gmail.com>

+ 43 - 19
vendor/src/gopkg.in/fsnotify.v1/CHANGELOG.md

@@ -1,53 +1,78 @@
 # Changelog
 
+## v1.2.10 / 2016-03-02
+
+* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj)
+
+## v1.2.9 / 2016-01-13
+
+kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep)
+
+## v1.2.8 / 2015-12-17
+
+* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test)
+* inotify: fix race in test
+* enable race detection for continuous integration (Linux, Mac, Windows)
+
+## v1.2.5 / 2015-10-17
+
+* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki)
+* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken)
+* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie)
+* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion)
+
+## v1.2.1 / 2015-10-14
+
+* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx)
+
 ## v1.2.0 / 2015-02-08
 
-* inotify: use epoll to wake up readEvents [#66](https://github.com/go-fsnotify/fsnotify/pull/66) (thanks @PieterD)
-* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/go-fsnotify/fsnotify/pull/63) (thanks @PieterD)
-* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/go-fsnotify/fsnotify/issues/59)
+* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD)
+* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD)
+* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59)
 
 ## v1.1.1 / 2015-02-05
 
-* inotify: Retry read on EINTR [#61](https://github.com/go-fsnotify/fsnotify/issues/61) (thanks @PieterD)
+* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD)
 
 ## v1.1.0 / 2014-12-12
 
-* kqueue: rework internals [#43](https://github.com/go-fsnotify/fsnotify/pull/43)
+* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43)
     * add low-level functions
     * only need to store flags on directories
-    * less mutexes [#13](https://github.com/go-fsnotify/fsnotify/issues/13)
+    * less mutexes [#13](https://github.com/fsnotify/fsnotify/issues/13)
     * done can be an unbuffered channel
     * remove calls to os.NewSyscallError
-* More efficient string concatenation for Event.String() [#52](https://github.com/go-fsnotify/fsnotify/pull/52) (thanks @mdlayher)
-* kqueue: fix regression in  rework causing subdirectories to be watched [#48](https://github.com/go-fsnotify/fsnotify/issues/48)
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/go-fsnotify/fsnotify/issues/51)
+* More efficient string concatenation for Event.String() [#52](https://github.com/fsnotify/fsnotify/pull/52) (thanks @mdlayher)
+* kqueue: fix regression in  rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48)
+* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
 
 ## v1.0.4 / 2014-09-07
 
 * kqueue: add dragonfly to the build tags.
 * Rename source code files, rearrange code so exported APIs are at the top.
-* Add done channel to example code. [#37](https://github.com/go-fsnotify/fsnotify/pull/37) (thanks @chenyukang)
+* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang)
 
 ## v1.0.3 / 2014-08-19
 
-* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/go-fsnotify/fsnotify/issues/36)
+* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36)
 
 ## v1.0.2 / 2014-08-17
 
-* [Fix] Missing create events on OS X. [#14](https://github.com/go-fsnotify/fsnotify/issues/14) (thanks @zhsso)
+* [Fix] Missing create events on OS X. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
 * [Fix] Make ./path and path equivalent. (thanks @zhsso)
 
 ## v1.0.0 / 2014-08-15
 
 * [API] Remove AddWatch on Windows, use Add.
-* Improve documentation for exported identifiers. [#30](https://github.com/go-fsnotify/fsnotify/issues/30)
+* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30)
 * Minor updates based on feedback from golint.
 
 ## dev / 2014-07-09
 
-* Moved to [github.com/go-fsnotify/fsnotify](https://github.com/go-fsnotify/fsnotify).
+* Moved to [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify).
 * Use os.NewSyscallError instead of returning errno (thanks @hariharan-uno)
- 
+
 ## dev / 2014-07-04
 
 * kqueue: fix incorrect mutex used in Close()
@@ -55,7 +80,7 @@
 
 ## dev / 2014-06-28
 
-* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/go-fsnotify/fsnotify/issues/4)
+* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/fsnotify/fsnotify/issues/4)
 * Fix for String() method on Event (thanks Alex Brainman)
 * Don't build on Plan 9 or Solaris (thanks @4ad)
 
@@ -93,11 +118,11 @@
 
 ## v0.9.3 / 2014-12-31
 
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/go-fsnotify/fsnotify/issues/51)
+* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
 
 ## v0.9.2 / 2014-08-17
 
-* [Backport] Fix missing create events on OS X. [#14](https://github.com/go-fsnotify/fsnotify/issues/14) (thanks @zhsso)
+* [Backport] Fix missing create events on OS X. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
 
 ## v0.9.1 / 2014-06-12
 
@@ -260,4 +285,3 @@
 [#25]: https://github.com/howeyc/fsnotify/issues/25
 [#24]: https://github.com/howeyc/fsnotify/issues/24
 [#21]: https://github.com/howeyc/fsnotify/issues/21
-

+ 4 - 4
vendor/src/gopkg.in/fsnotify.v1/CONTRIBUTING.md

@@ -2,7 +2,7 @@
 
 ## Issues
 
-* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/go-fsnotify/fsnotify/issues).
+* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnotify/fsnotify/issues).
 * Please indicate the platform you are using fsnotify on.
 * A code example to reproduce the problem is appreciated.
 
@@ -10,7 +10,7 @@
 
 ### Contributor License Agreement
 
-fsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/go-fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/go-fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual).
+fsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual).
 
 Please indicate that you have signed the CLA in your pull request.
 
@@ -28,7 +28,7 @@ Please indicate that you have signed the CLA in your pull request.
 
 For smooth sailing, always use the original import path. Installing with `go get` makes this easy. 
 
-1. Install from GitHub (`go get -u github.com/go-fsnotify/fsnotify`)
+1. Install from GitHub (`go get -u github.com/fsnotify/fsnotify`)
 2. Create your feature branch (`git checkout -b my-new-feature`)
 3. Ensure everything works and the tests pass (see below)
 4. Commit your changes (`git commit -am 'Add some feature'`)
@@ -53,7 +53,7 @@ To aid in cross-platform testing there is a Vagrantfile for Linux and BSD.
 * Install [Vagrant](http://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/)
 * Setup [Vagrant Gopher](https://github.com/nathany/vagrant-gopher) in your `src` folder.
 * Run `vagrant up` from the project folder. You can also setup just one box with `vagrant up linux` or `vagrant up bsd` (note: the BSD box doesn't support Windows hosts at this time, and NFS may prompt for your host OS password)
-* Once setup, you can run the test suite on a given OS with a single command `vagrant ssh linux -c 'cd go-fsnotify/fsnotify; go test'`.
+* Once setup, you can run the test suite on a given OS with a single command `vagrant ssh linux -c 'cd fsnotify/fsnotify; go test'`.
 * When you're done, you will want to halt or destroy the Vagrant boxes.
 
 Notice: fsnotify file system events won't trigger in shared folders. The tests get around this limitation by using the /tmp directory.

+ 0 - 0
vendor/src/gopkg.in/fsnotify.v1/NotUsed.xcworkspace


+ 18 - 31
vendor/src/gopkg.in/fsnotify.v1/README.md

@@ -1,6 +1,6 @@
 # File system notifications for Go
 
-[![Coverage](http://gocover.io/_badge/github.com/go-fsnotify/fsnotify)](http://gocover.io/github.com/go-fsnotify/fsnotify) [![GoDoc](https://godoc.org/gopkg.in/fsnotify.v1?status.svg)](https://godoc.org/gopkg.in/fsnotify.v1)
+[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Coverage](http://gocover.io/_badge/github.com/fsnotify/fsnotify)](http://gocover.io/github.com/fsnotify/fsnotify) 
 
 Go 1.3+ required.
 
@@ -8,44 +8,26 @@ Cross platform: Windows, Linux, BSD and OS X.
 
 |Adapter   |OS        |Status    |
 |----------|----------|----------|
-|inotify   |Linux, Android\*|Supported [![Build Status](https://travis-ci.org/go-fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/go-fsnotify/fsnotify)|
-|kqueue    |BSD, OS X, iOS\*|Supported [![Circle CI](https://circleci.com/gh/go-fsnotify/fsnotify.svg?style=svg)](https://circleci.com/gh/go-fsnotify/fsnotify)|
+|inotify   |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
+|kqueue    |BSD, OS X, iOS\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
 |ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
-|FSEvents  |OS X          |[Planned](https://github.com/go-fsnotify/fsnotify/issues/11)|
-|FEN       |Solaris 11    |[Planned](https://github.com/go-fsnotify/fsnotify/issues/12)|
+|FSEvents  |OS X          |[Planned](https://github.com/fsnotify/fsnotify/issues/11)|
+|FEN       |Solaris 11    |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)|
 |fanotify  |Linux 2.6.37+ | |
-|USN Journals |Windows    |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/53)|
-|Polling   |*All*         |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/9)|
+|USN Journals |Windows    |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)|
+|Polling   |*All*         |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)|
 
 \* Android and iOS are untested.
 
-Please see [the documentation](https://godoc.org/gopkg.in/fsnotify.v1) for usage. Consult the [Wiki](https://github.com/go-fsnotify/fsnotify/wiki) for the FAQ and further information.
+Please see [the documentation](https://godoc.org/github.com/fsnotify/fsnotify) for usage. Consult the [Wiki](https://github.com/fsnotify/fsnotify/wiki) for the FAQ and further information.
 
 ## API stability
 
-Two major versions of fsnotify exist. 
+fsnotify is a fork of [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA). 
 
-**[fsnotify.v0](https://gopkg.in/fsnotify.v0)** is API-compatible with [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify). Bugfixes *may* be backported, but I recommend upgrading to v1.
+All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). Further API changes are [planned](https://github.com/fsnotify/fsnotify/milestones), and will be tagged with a new major revision number.
 
-```go
-import "gopkg.in/fsnotify.v0"
-```
-
-\* Refer to the package as fsnotify (without the .v0 suffix).
-
-**[fsnotify.v1](https://gopkg.in/fsnotify.v1)** provides [a new API](https://godoc.org/gopkg.in/fsnotify.v1) based on [this design document](http://goo.gl/MrYxyA). You can import v1 with:
-
-```go
-import "gopkg.in/fsnotify.v1"
-```
-
-Further API changes are [planned](https://github.com/go-fsnotify/fsnotify/milestones), but a new major revision will be tagged, so you can depend on the v1 API.
-
-**Master** may have unreleased changes. Use it to test the very latest code or when [contributing][], but don't expect it to remain API-compatible:
-
-```go
-import "github.com/go-fsnotify/fsnotify"
-```
+Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project.
 
 ## Contributing
 
@@ -53,7 +35,12 @@ Please refer to [CONTRIBUTING][] before opening an issue or pull request.
 
 ## Example
 
-See [example_test.go](https://github.com/go-fsnotify/fsnotify/blob/master/example_test.go).
+See [example_test.go](https://github.com/fsnotify/fsnotify/blob/master/example_test.go).
+
+[contributing]: https://github.com/fsnotify/fsnotify/blob/master/CONTRIBUTING.md
+
+## Related Projects
 
+* [notify](https://github.com/rjeczalik/notify)
+* [fsevents](https://github.com/fsnotify/fsevents)
 
-[contributing]: https://github.com/go-fsnotify/fsnotify/blob/master/CONTRIBUTING.md

+ 0 - 26
vendor/src/gopkg.in/fsnotify.v1/circle.yml

@@ -1,26 +0,0 @@
-## OS X build (CircleCI iOS beta)
-
-# Pretend like it's an Xcode project, at least to get it running.
-machine:
-  environment:
-    XCODE_WORKSPACE: NotUsed.xcworkspace
-    XCODE_SCHEME: NotUsed
-    # This is where the go project is actually checked out to:
-    CIRCLE_BUILD_DIR: $HOME/.go_project/src/github.com/go-fsnotify/fsnotify
-
-dependencies:
-  pre:
-    - brew upgrade go
-
-test:
-  override:
-    - go test ./...
-
-# Idealized future config, eventually with cross-platform build matrix :-)
-
-# machine:
-#   go:
-#     version: 1.4
-#   os:
-#     - osx
-#     - linux

+ 37 - 0
vendor/src/gopkg.in/fsnotify.v1/fen.go

@@ -0,0 +1,37 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build solaris
+
+package fsnotify
+
+import (
+	"errors"
+)
+
+// Watcher watches a set of files, delivering events to a channel.
+type Watcher struct {
+	Events chan Event
+	Errors chan error
+}
+
+// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
+func NewWatcher() (*Watcher, error) {
+	return nil, errors.New("FEN based watcher not yet supported for fsnotify\n")
+}
+
+// Close removes all watches and closes the events channel.
+func (w *Watcher) Close() error {
+	return nil
+}
+
+// Add starts watching the named file or directory (non-recursively).
+func (w *Watcher) Add(name string) error {
+	return nil
+}
+
+// Remove stops watching the the named file or directory (non-recursively).
+func (w *Watcher) Remove(name string) error {
+	return nil
+}

+ 1 - 1
vendor/src/gopkg.in/fsnotify.v1/fsnotify.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !plan9,!solaris
+// +build !plan9
 
 // Package fsnotify provides a platform-independent interface for file system notifications.
 package fsnotify

+ 23 - 5
vendor/src/gopkg.in/fsnotify.v1/inotify.go

@@ -23,6 +23,7 @@ type Watcher struct {
 	Events   chan Event
 	Errors   chan error
 	mu       sync.Mutex // Map access
+	cv       *sync.Cond // sync removing on rm_watch with IN_IGNORE
 	fd       int
 	poller   *fdPoller
 	watches  map[string]*watch // Map of inotify watches (key: path)
@@ -54,6 +55,7 @@ func NewWatcher() (*Watcher, error) {
 		done:     make(chan struct{}),
 		doneResp: make(chan struct{}),
 	}
+	w.cv = sync.NewCond(&w.mu)
 
 	go w.readEvents()
 	return w, nil
@@ -134,8 +136,10 @@ func (w *Watcher) Remove(name string) error {
 	}
 	// inotify_rm_watch will return EINVAL if the file has been deleted;
 	// the inotify will already have been removed.
-	// That means we can safely delete it from our watches, whatever inotify_rm_watch does.
-	delete(w.watches, name)
+	// watches and pathes are deleted in ignoreLinux() implicitly and asynchronously
+	// by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE
+	// so that EINVAL means that the wd is being rm_watch()ed or its file removed
+	// by another thread and we have not received IN_IGNORE event.
 	success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
 	if success == -1 {
 		// TODO: Perhaps it's not helpful to return an error here in every case.
@@ -146,6 +150,14 @@ func (w *Watcher) Remove(name string) error {
 		// explicitly by inotify_rm_watch, implicitly when the file they are watching is deleted.
 		return errno
 	}
+
+	// wait until ignoreLinux() deleting maps
+	exists := true
+	for exists {
+		w.cv.Wait()
+		_, exists = w.watches[name]
+	}
+
 	return nil
 }
 
@@ -209,7 +221,7 @@ func (w *Watcher) readEvents() {
 				// If EOF is received. This should really never happen.
 				err = io.EOF
 			} else if n < 0 {
-				// If an error occured while reading.
+				// If an error occurred while reading.
 				err = errno
 			} else {
 				// Read was too short.
@@ -249,7 +261,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 !event.ignoreLinux(w, raw.Wd, mask) {
 				select {
 				case w.Events <- event:
 				case <-w.done:
@@ -266,9 +278,15 @@ 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 {
+func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
 	// Ignore anything the inotify API says to ignore
 	if mask&syscall.IN_IGNORED == syscall.IN_IGNORED {
+		w.mu.Lock()
+		defer w.mu.Unlock()
+		name := w.paths[int(wd)]
+		delete(w.paths, int(wd))
+		delete(w.watches, name)
+		w.cv.Broadcast()
 		return true
 	}
 

+ 1 - 1
vendor/src/gopkg.in/fsnotify.v1/inotify_poller.go

@@ -39,7 +39,7 @@ func newFdPoller(fd int) (*fdPoller, error) {
 	poller.fd = fd
 
 	// Create epoll fd
-	poller.epfd, errno = syscall.EpollCreate(1)
+	poller.epfd, errno = syscall.EpollCreate1(0)
 	if poller.epfd == -1 {
 		return nil, errno
 	}

+ 80 - 41
vendor/src/gopkg.in/fsnotify.v1/kqueue.go

@@ -72,12 +72,17 @@ func (w *Watcher) Close() error {
 	w.isClosed = true
 	w.mu.Unlock()
 
+	// copy paths to remove while locked
 	w.mu.Lock()
-	ws := w.watches
+	var pathsToRemove = make([]string, 0, len(w.watches))
+	for name := range w.watches {
+		pathsToRemove = append(pathsToRemove, name)
+	}
 	w.mu.Unlock()
+	// unlock before calling Remove, which also locks
 
 	var err error
-	for name := range ws {
+	for _, name := range pathsToRemove {
 		if e := w.Remove(name); e != nil && err == nil {
 			err = e
 		}
@@ -94,7 +99,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 +159,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 +168,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 +180,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 +202,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 +230,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 +244,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 +253,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
@@ -304,19 +325,24 @@ func (w *Watcher) readEvents() {
 			if event.Op&Remove == Remove {
 				// Look for a file that may have overwritten this.
 				// For example, mv f1 f2 will delete f2, then create f2.
-				fileDir, _ := filepath.Split(event.Name)
-				fileDir = filepath.Clean(fileDir)
-				w.mu.Lock()
-				_, found := w.watches[fileDir]
-				w.mu.Unlock()
-				if found {
-					// make sure the directory exists before we watch for changes. When we
-					// do a recursive watch and perform rm -fr, the parent directory might
-					// have gone missing, ignore the missing directory and let the
-					// upcoming delete event remove the watch from the parent directory.
-					if _, err := os.Lstat(fileDir); os.IsExist(err) {
-						w.sendDirectoryChangeEvents(fileDir)
-						// FIXME: should this be for events on files or just isDir?
+				if path.isDir {
+					fileDir := filepath.Clean(event.Name)
+					w.mu.Lock()
+					_, found := w.watches[fileDir]
+					w.mu.Unlock()
+					if found {
+						// make sure the directory exists before we watch for changes. When we
+						// do a recursive watch and perform rm -fr, the parent directory might
+						// have gone missing, ignore the missing directory and let the
+						// upcoming delete event remove the watch from the parent directory.
+						if _, err := os.Lstat(fileDir); err == nil {
+							w.sendDirectoryChangeEvents(fileDir)
+						}
+					}
+				} else {
+					filePath := filepath.Clean(event.Name)
+					if fileInfo, err := os.Lstat(filePath); err == nil {
+						w.sendFileCreatedEventIfNew(filePath, fileInfo)
 					}
 				}
 			}
@@ -359,7 +385,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
 		}
 
@@ -385,26 +412,38 @@ func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
 	// Search for new files
 	for _, fileInfo := range files {
 		filePath := filepath.Join(dirPath, fileInfo.Name())
-		w.mu.Lock()
-		_, doesExist := w.fileExists[filePath]
-		w.mu.Unlock()
-		if !doesExist {
-			// Send create event
-			w.Events <- newCreateEvent(filePath)
-		}
+		err := w.sendFileCreatedEventIfNew(filePath, fileInfo)
 
-		// like watchDirectoryFiles (but without doing another ReadDir)
-		if err := w.internalWatch(filePath, fileInfo); err != nil {
+		if err != nil {
 			return
 		}
+	}
+}
 
-		w.mu.Lock()
-		w.fileExists[filePath] = true
-		w.mu.Unlock()
+// sendFileCreatedEvent sends a create event if the file isn't already being tracked.
+func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) {
+	w.mu.Lock()
+	_, doesExist := w.fileExists[filePath]
+	w.mu.Unlock()
+	if !doesExist {
+		// Send create event
+		w.Events <- newCreateEvent(filePath)
 	}
+
+	// like watchDirectoryFiles (but without doing another ReadDir)
+	filePath, err = w.internalWatch(filePath, fileInfo)
+	if err != nil {
+		return err
+	}
+
+	w.mu.Lock()
+	w.fileExists[filePath] = true
+	w.mu.Unlock()
+
+	return nil
 }
 
-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 +451,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)
 	}
 

+ 46 - 46
vendor/src/gopkg.in/fsnotify.v1/windows.go

@@ -71,7 +71,7 @@ func (w *Watcher) Add(name string) error {
 	in := &input{
 		op:    opAddWatch,
 		path:  filepath.Clean(name),
-		flags: sys_FS_ALL_EVENTS,
+		flags: sysFSALLEVENTS,
 		reply: make(chan error),
 	}
 	w.input <- in
@@ -97,43 +97,43 @@ func (w *Watcher) Remove(name string) error {
 
 const (
 	// Options for AddWatch
-	sys_FS_ONESHOT = 0x80000000
-	sys_FS_ONLYDIR = 0x1000000
+	sysFSONESHOT = 0x80000000
+	sysFSONLYDIR = 0x1000000
 
 	// Events
-	sys_FS_ACCESS      = 0x1
-	sys_FS_ALL_EVENTS  = 0xfff
-	sys_FS_ATTRIB      = 0x4
-	sys_FS_CLOSE       = 0x18
-	sys_FS_CREATE      = 0x100
-	sys_FS_DELETE      = 0x200
-	sys_FS_DELETE_SELF = 0x400
-	sys_FS_MODIFY      = 0x2
-	sys_FS_MOVE        = 0xc0
-	sys_FS_MOVED_FROM  = 0x40
-	sys_FS_MOVED_TO    = 0x80
-	sys_FS_MOVE_SELF   = 0x800
+	sysFSACCESS     = 0x1
+	sysFSALLEVENTS  = 0xfff
+	sysFSATTRIB     = 0x4
+	sysFSCLOSE      = 0x18
+	sysFSCREATE     = 0x100
+	sysFSDELETE     = 0x200
+	sysFSDELETESELF = 0x400
+	sysFSMODIFY     = 0x2
+	sysFSMOVE       = 0xc0
+	sysFSMOVEDFROM  = 0x40
+	sysFSMOVEDTO    = 0x80
+	sysFSMOVESELF   = 0x800
 
 	// Special events
-	sys_FS_IGNORED    = 0x8000
-	sys_FS_Q_OVERFLOW = 0x4000
+	sysFSIGNORED   = 0x8000
+	sysFSQOVERFLOW = 0x4000
 )
 
 func newEvent(name string, mask uint32) Event {
 	e := Event{Name: name}
-	if mask&sys_FS_CREATE == sys_FS_CREATE || mask&sys_FS_MOVED_TO == sys_FS_MOVED_TO {
+	if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO {
 		e.Op |= Create
 	}
-	if mask&sys_FS_DELETE == sys_FS_DELETE || mask&sys_FS_DELETE_SELF == sys_FS_DELETE_SELF {
+	if mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF {
 		e.Op |= Remove
 	}
-	if mask&sys_FS_MODIFY == sys_FS_MODIFY {
+	if mask&sysFSMODIFY == sysFSMODIFY {
 		e.Op |= Write
 	}
-	if mask&sys_FS_MOVE == sys_FS_MOVE || mask&sys_FS_MOVE_SELF == sys_FS_MOVE_SELF || mask&sys_FS_MOVED_FROM == sys_FS_MOVED_FROM {
+	if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM {
 		e.Op |= Rename
 	}
-	if mask&sys_FS_ATTRIB == sys_FS_ATTRIB {
+	if mask&sysFSATTRIB == sysFSATTRIB {
 		e.Op |= Chmod
 	}
 	return e
@@ -242,7 +242,7 @@ func (w *Watcher) addWatch(pathname string, flags uint64) error {
 	if err != nil {
 		return err
 	}
-	if flags&sys_FS_ONLYDIR != 0 && pathname != dir {
+	if flags&sysFSONLYDIR != 0 && pathname != dir {
 		return nil
 	}
 	ino, err := getIno(dir)
@@ -302,11 +302,11 @@ func (w *Watcher) remWatch(pathname string) error {
 		return fmt.Errorf("can't remove non-existent watch for: %s", pathname)
 	}
 	if pathname == dir {
-		w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED)
+		w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
 		watch.mask = 0
 	} else {
 		name := filepath.Base(pathname)
-		w.sendEvent(watch.path+"\\"+name, watch.names[name]&sys_FS_IGNORED)
+		w.sendEvent(watch.path+"\\"+name, watch.names[name]&sysFSIGNORED)
 		delete(watch.names, name)
 	}
 	return w.startRead(watch)
@@ -316,13 +316,13 @@ func (w *Watcher) remWatch(pathname string) error {
 func (w *Watcher) deleteWatch(watch *watch) {
 	for name, mask := range watch.names {
 		if mask&provisional == 0 {
-			w.sendEvent(watch.path+"\\"+name, mask&sys_FS_IGNORED)
+			w.sendEvent(watch.path+"\\"+name, mask&sysFSIGNORED)
 		}
 		delete(watch.names, name)
 	}
 	if watch.mask != 0 {
 		if watch.mask&provisional == 0 {
-			w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED)
+			w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
 		}
 		watch.mask = 0
 	}
@@ -353,8 +353,8 @@ func (w *Watcher) startRead(watch *watch) error {
 		err := os.NewSyscallError("ReadDirectoryChanges", e)
 		if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
 			// Watched directory was probably removed
-			if w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF) {
-				if watch.mask&sys_FS_ONESHOT != 0 {
+			if w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) {
+				if watch.mask&sysFSONESHOT != 0 {
 					watch.mask = 0
 				}
 			}
@@ -428,7 +428,7 @@ func (w *Watcher) readEvents() {
 			}
 		case syscall.ERROR_ACCESS_DENIED:
 			// Watched directory was probably removed
-			w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF)
+			w.sendEvent(watch.path, watch.mask&sysFSDELETESELF)
 			w.deleteWatch(watch)
 			w.startRead(watch)
 			continue
@@ -444,7 +444,7 @@ func (w *Watcher) readEvents() {
 		var offset uint32
 		for {
 			if n == 0 {
-				w.Events <- newEvent("", sys_FS_Q_OVERFLOW)
+				w.Events <- newEvent("", sysFSQOVERFLOW)
 				w.Errors <- errors.New("short read in readEvents()")
 				break
 			}
@@ -458,22 +458,22 @@ func (w *Watcher) readEvents() {
 			var mask uint64
 			switch raw.Action {
 			case syscall.FILE_ACTION_REMOVED:
-				mask = sys_FS_DELETE_SELF
+				mask = sysFSDELETESELF
 			case syscall.FILE_ACTION_MODIFIED:
-				mask = sys_FS_MODIFY
+				mask = sysFSMODIFY
 			case syscall.FILE_ACTION_RENAMED_OLD_NAME:
 				watch.rename = name
 			case syscall.FILE_ACTION_RENAMED_NEW_NAME:
 				if watch.names[watch.rename] != 0 {
 					watch.names[name] |= watch.names[watch.rename]
 					delete(watch.names, watch.rename)
-					mask = sys_FS_MOVE_SELF
+					mask = sysFSMOVESELF
 				}
 			}
 
 			sendNameEvent := func() {
 				if w.sendEvent(fullname, watch.names[name]&mask) {
-					if watch.names[name]&sys_FS_ONESHOT != 0 {
+					if watch.names[name]&sysFSONESHOT != 0 {
 						delete(watch.names, name)
 					}
 				}
@@ -482,11 +482,11 @@ func (w *Watcher) readEvents() {
 				sendNameEvent()
 			}
 			if raw.Action == syscall.FILE_ACTION_REMOVED {
-				w.sendEvent(fullname, watch.names[name]&sys_FS_IGNORED)
+				w.sendEvent(fullname, watch.names[name]&sysFSIGNORED)
 				delete(watch.names, name)
 			}
 			if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) {
-				if watch.mask&sys_FS_ONESHOT != 0 {
+				if watch.mask&sysFSONESHOT != 0 {
 					watch.mask = 0
 				}
 			}
@@ -529,16 +529,16 @@ func (w *Watcher) sendEvent(name string, mask uint64) bool {
 
 func toWindowsFlags(mask uint64) uint32 {
 	var m uint32
-	if mask&sys_FS_ACCESS != 0 {
+	if mask&sysFSACCESS != 0 {
 		m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS
 	}
-	if mask&sys_FS_MODIFY != 0 {
+	if mask&sysFSMODIFY != 0 {
 		m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE
 	}
-	if mask&sys_FS_ATTRIB != 0 {
+	if mask&sysFSATTRIB != 0 {
 		m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES
 	}
-	if mask&(sys_FS_MOVE|sys_FS_CREATE|sys_FS_DELETE) != 0 {
+	if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 {
 		m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME
 	}
 	return m
@@ -547,15 +547,15 @@ func toWindowsFlags(mask uint64) uint32 {
 func toFSnotifyFlags(action uint32) uint64 {
 	switch action {
 	case syscall.FILE_ACTION_ADDED:
-		return sys_FS_CREATE
+		return sysFSCREATE
 	case syscall.FILE_ACTION_REMOVED:
-		return sys_FS_DELETE
+		return sysFSDELETE
 	case syscall.FILE_ACTION_MODIFIED:
-		return sys_FS_MODIFY
+		return sysFSMODIFY
 	case syscall.FILE_ACTION_RENAMED_OLD_NAME:
-		return sys_FS_MOVED_FROM
+		return sysFSMOVEDFROM
 	case syscall.FILE_ACTION_RENAMED_NEW_NAME:
-		return sys_FS_MOVED_TO
+		return sysFSMOVEDTO
 	}
 	return 0
 }