aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/rjeczalik
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/rjeczalik')
-rw-r--r--vendor/github.com/rjeczalik/notify/README.md2
-rw-r--r--vendor/github.com/rjeczalik/notify/appveyor.yml2
-rw-r--r--vendor/github.com/rjeczalik/notify/debug.go50
-rw-r--r--vendor/github.com/rjeczalik/notify/debug_debug.go36
-rw-r--r--vendor/github.com/rjeczalik/notify/debug_nodebug.go9
-rw-r--r--vendor/github.com/rjeczalik/notify/doc.go7
-rw-r--r--vendor/github.com/rjeczalik/notify/event.go2
-rw-r--r--vendor/github.com/rjeczalik/notify/event_inotify.go40
-rw-r--r--vendor/github.com/rjeczalik/notify/event_readdcw.go14
-rw-r--r--vendor/github.com/rjeczalik/notify/node.go7
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fen.go11
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fsevents.go8
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go13
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go9
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go14
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_inotify.go79
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_kqueue.go14
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_readdcw.go50
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_trigger.go21
19 files changed, 231 insertions, 157 deletions
diff --git a/vendor/github.com/rjeczalik/notify/README.md b/vendor/github.com/rjeczalik/notify/README.md
index a728d1dd0..02a5f3290 100644
--- a/vendor/github.com/rjeczalik/notify/README.md
+++ b/vendor/github.com/rjeczalik/notify/README.md
@@ -18,4 +18,4 @@ Filesystem event notification library on steroids. (under active development)
- [github.com/rjeczalik/cmd/notify](https://godoc.org/github.com/rjeczalik/cmd/notify)
- [github.com/cortesi/devd](https://github.com/cortesi/devd)
- [github.com/cortesi/modd](https://github.com/cortesi/modd)
-
+- [github.com/syncthing/syncthing-inotify](https://github.com/syncthing/syncthing-inotify)
diff --git a/vendor/github.com/rjeczalik/notify/appveyor.yml b/vendor/github.com/rjeczalik/notify/appveyor.yml
index 8e762d05c..a495bd7c7 100644
--- a/vendor/github.com/rjeczalik/notify/appveyor.yml
+++ b/vendor/github.com/rjeczalik/notify/appveyor.yml
@@ -16,7 +16,7 @@ install:
build_script:
- go tool vet -all .
- go build ./...
- - go test -v -race ./...
+ - go test -v -timeout 60s -race ./...
test: off
diff --git a/vendor/github.com/rjeczalik/notify/debug.go b/vendor/github.com/rjeczalik/notify/debug.go
index bd9bc468d..2a3eb3370 100644
--- a/vendor/github.com/rjeczalik/notify/debug.go
+++ b/vendor/github.com/rjeczalik/notify/debug.go
@@ -2,10 +2,52 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
-// +build !debug
-
package notify
-func dbgprint(...interface{}) {}
+import (
+ "log"
+ "os"
+ "runtime"
+ "strings"
+)
+
+var dbgprint func(...interface{})
+
+var dbgprintf func(string, ...interface{})
+
+var dbgcallstack func(max int) []string
-func dbgprintf(string, ...interface{}) {}
+func init() {
+ if _, ok := os.LookupEnv("NOTIFY_DEBUG"); ok || debugTag {
+ log.SetOutput(os.Stdout)
+ log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
+ dbgprint = func(v ...interface{}) {
+ v = append([]interface{}{"[D] "}, v...)
+ log.Println(v...)
+ }
+ dbgprintf = func(format string, v ...interface{}) {
+ format = "[D] " + format
+ log.Printf(format, v...)
+ }
+ dbgcallstack = func(max int) []string {
+ pc, stack := make([]uintptr, max), make([]string, 0, max)
+ runtime.Callers(2, pc)
+ for _, pc := range pc {
+ if f := runtime.FuncForPC(pc); f != nil {
+ fname := f.Name()
+ idx := strings.LastIndex(fname, string(os.PathSeparator))
+ if idx != -1 {
+ stack = append(stack, fname[idx+1:])
+ } else {
+ stack = append(stack, fname)
+ }
+ }
+ }
+ return stack
+ }
+ return
+ }
+ dbgprint = func(v ...interface{}) {}
+ dbgprintf = func(format string, v ...interface{}) {}
+ dbgcallstack = func(max int) []string { return nil }
+}
diff --git a/vendor/github.com/rjeczalik/notify/debug_debug.go b/vendor/github.com/rjeczalik/notify/debug_debug.go
index f0622917f..6fca891ab 100644
--- a/vendor/github.com/rjeczalik/notify/debug_debug.go
+++ b/vendor/github.com/rjeczalik/notify/debug_debug.go
@@ -6,38 +6,4 @@
package notify
-import (
- "fmt"
- "os"
- "runtime"
- "strings"
-)
-
-func dbgprint(v ...interface{}) {
- fmt.Printf("[D] ")
- fmt.Print(v...)
- fmt.Printf("\n\n")
-}
-
-func dbgprintf(format string, v ...interface{}) {
- fmt.Printf("[D] ")
- fmt.Printf(format, v...)
- fmt.Printf("\n\n")
-}
-
-func dbgcallstack(max int) []string {
- pc, stack := make([]uintptr, max), make([]string, 0, max)
- runtime.Callers(2, pc)
- for _, pc := range pc {
- if f := runtime.FuncForPC(pc); f != nil {
- fname := f.Name()
- idx := strings.LastIndex(fname, string(os.PathSeparator))
- if idx != -1 {
- stack = append(stack, fname[idx+1:])
- } else {
- stack = append(stack, fname)
- }
- }
- }
- return stack
-}
+var debugTag bool = true
diff --git a/vendor/github.com/rjeczalik/notify/debug_nodebug.go b/vendor/github.com/rjeczalik/notify/debug_nodebug.go
new file mode 100644
index 000000000..be391a276
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/debug_nodebug.go
@@ -0,0 +1,9 @@
+// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build !debug
+
+package notify
+
+var debugTag bool = false
diff --git a/vendor/github.com/rjeczalik/notify/doc.go b/vendor/github.com/rjeczalik/notify/doc.go
index 8a99ddda6..60543c083 100644
--- a/vendor/github.com/rjeczalik/notify/doc.go
+++ b/vendor/github.com/rjeczalik/notify/doc.go
@@ -12,11 +12,14 @@
// source file.
//
// On top of filesystem watchers notify maintains a watchpoint tree, which provides
-// strategy for creating and closing filesystem watches and dispatching filesystem
+// a strategy for creating and closing filesystem watches and dispatching filesystem
// events to user channels.
//
// An event set is just an event list joint using bitwise OR operator
// into a single event value.
+// Both the platform-independent (see Constants) and specific events can be used.
+// Refer to the event_*.go source files for information about the available
+// events.
//
// A filesystem watch or just a watch is platform-specific entity which represents
// a single path registered for notifications for specific event set. Setting a watch
@@ -35,6 +38,6 @@
// A watchpoint is a list of user channel and event set pairs for particular
// path (watchpoint tree's node). A single watchpoint can contain multiple
// different user channels registered to listen for one or more events. A single
-// user channel can be registered in one or more watchpoints, recurisve and
+// user channel can be registered in one or more watchpoints, recursive and
// non-recursive ones as well.
package notify
diff --git a/vendor/github.com/rjeczalik/notify/event.go b/vendor/github.com/rjeczalik/notify/event.go
index e045edcec..c12884197 100644
--- a/vendor/github.com/rjeczalik/notify/event.go
+++ b/vendor/github.com/rjeczalik/notify/event.go
@@ -73,7 +73,7 @@ func (e Event) String() string {
//
// https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamEventFlags
//
-// Under Linux (inotify) Sys() always returns a non-nil *syscall.InotifyEvent
+// Under Linux (inotify) Sys() always returns a non-nil *unix.InotifyEvent
// value, defined as:
//
// type InotifyEvent struct {
diff --git a/vendor/github.com/rjeczalik/notify/event_inotify.go b/vendor/github.com/rjeczalik/notify/event_inotify.go
index 82954a9b3..1f32bb73e 100644
--- a/vendor/github.com/rjeczalik/notify/event_inotify.go
+++ b/vendor/github.com/rjeczalik/notify/event_inotify.go
@@ -6,7 +6,7 @@
package notify
-import "syscall"
+import "golang.org/x/sys/unix"
// Platform independent event values.
const (
@@ -25,18 +25,18 @@ const (
// Inotify specific masks are legal, implemented events that are guaranteed to
// work with notify package on linux-based systems.
const (
- InAccess = Event(syscall.IN_ACCESS) // File was accessed
- InModify = Event(syscall.IN_MODIFY) // File was modified
- InAttrib = Event(syscall.IN_ATTRIB) // Metadata changed
- InCloseWrite = Event(syscall.IN_CLOSE_WRITE) // Writtable file was closed
- InCloseNowrite = Event(syscall.IN_CLOSE_NOWRITE) // Unwrittable file closed
- InOpen = Event(syscall.IN_OPEN) // File was opened
- InMovedFrom = Event(syscall.IN_MOVED_FROM) // File was moved from X
- InMovedTo = Event(syscall.IN_MOVED_TO) // File was moved to Y
- InCreate = Event(syscall.IN_CREATE) // Subfile was created
- InDelete = Event(syscall.IN_DELETE) // Subfile was deleted
- InDeleteSelf = Event(syscall.IN_DELETE_SELF) // Self was deleted
- InMoveSelf = Event(syscall.IN_MOVE_SELF) // Self was moved
+ InAccess = Event(unix.IN_ACCESS) // File was accessed
+ InModify = Event(unix.IN_MODIFY) // File was modified
+ InAttrib = Event(unix.IN_ATTRIB) // Metadata changed
+ InCloseWrite = Event(unix.IN_CLOSE_WRITE) // Writtable file was closed
+ InCloseNowrite = Event(unix.IN_CLOSE_NOWRITE) // Unwrittable file closed
+ InOpen = Event(unix.IN_OPEN) // File was opened
+ InMovedFrom = Event(unix.IN_MOVED_FROM) // File was moved from X
+ InMovedTo = Event(unix.IN_MOVED_TO) // File was moved to Y
+ InCreate = Event(unix.IN_CREATE) // Subfile was created
+ InDelete = Event(unix.IN_DELETE) // Subfile was deleted
+ InDeleteSelf = Event(unix.IN_DELETE_SELF) // Self was deleted
+ InMoveSelf = Event(unix.IN_MOVE_SELF) // Self was moved
)
var osestr = map[Event]string{
@@ -56,15 +56,15 @@ var osestr = map[Event]string{
// Inotify behavior events are not **currently** supported by notify package.
const (
- inDontFollow = Event(syscall.IN_DONT_FOLLOW)
- inExclUnlink = Event(syscall.IN_EXCL_UNLINK)
- inMaskAdd = Event(syscall.IN_MASK_ADD)
- inOneshot = Event(syscall.IN_ONESHOT)
- inOnlydir = Event(syscall.IN_ONLYDIR)
+ inDontFollow = Event(unix.IN_DONT_FOLLOW)
+ inExclUnlink = Event(unix.IN_EXCL_UNLINK)
+ inMaskAdd = Event(unix.IN_MASK_ADD)
+ inOneshot = Event(unix.IN_ONESHOT)
+ inOnlydir = Event(unix.IN_ONLYDIR)
)
type event struct {
- sys syscall.InotifyEvent
+ sys unix.InotifyEvent
path string
event Event
}
@@ -72,4 +72,4 @@ type event struct {
func (e *event) Event() Event { return e.event }
func (e *event) Path() string { return e.path }
func (e *event) Sys() interface{} { return &e.sys }
-func (e *event) isDir() (bool, error) { return e.sys.Mask&syscall.IN_ISDIR != 0, nil }
+func (e *event) isDir() (bool, error) { return e.sys.Mask&unix.IN_ISDIR != 0, nil }
diff --git a/vendor/github.com/rjeczalik/notify/event_readdcw.go b/vendor/github.com/rjeczalik/notify/event_readdcw.go
index 11ead9e29..f7b82de0c 100644
--- a/vendor/github.com/rjeczalik/notify/event_readdcw.go
+++ b/vendor/github.com/rjeczalik/notify/event_readdcw.go
@@ -27,7 +27,11 @@ const (
dirmarker
)
-// ReadDirectoryChangesW filters.
+// ReadDirectoryChangesW filters
+// On Windows the following events can be passed to Watch. A different set of
+// events (see actions below) are received on the channel passed to Watch.
+// For more information refer to
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx
const (
FileNotifyChangeFileName = Event(syscall.FILE_NOTIFY_CHANGE_FILE_NAME)
FileNotifyChangeDirName = Event(syscall.FILE_NOTIFY_CHANGE_DIR_NAME)
@@ -48,7 +52,13 @@ const (
// this flag should be declared in: http://golang.org/src/pkg/syscall/ztypes_windows.go
const syscallFileNotifyChangeSecurity = 0x00000100
-// ReadDirectoryChangesW actions.
+// ReadDirectoryChangesW actions
+// The following events are returned on the channel passed to Watch, but cannot
+// be passed to Watch itself (see filters above). You can find a table showing
+// the relation between actions and filteres at
+// https://github.com/rjeczalik/notify/issues/10#issuecomment-66179535
+// The msdn documentation on actions is part of
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364391(v=vs.85).aspx
const (
FileActionAdded = Event(syscall.FILE_ACTION_ADDED) << 12
FileActionRemoved = Event(syscall.FILE_ACTION_REMOVED) << 12
diff --git a/vendor/github.com/rjeczalik/notify/node.go b/vendor/github.com/rjeczalik/notify/node.go
index 29c1bb20a..aced8b9c4 100644
--- a/vendor/github.com/rjeczalik/notify/node.go
+++ b/vendor/github.com/rjeczalik/notify/node.go
@@ -6,7 +6,6 @@ package notify
import (
"errors"
- "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -71,7 +70,11 @@ Traverse:
case errSkip:
continue Traverse
default:
- return fmt.Errorf("error while traversing %q: %v", nd.Name, err)
+ return &os.PathError{
+ Op: "error while traversing",
+ Path: nd.Name,
+ Err: err,
+ }
}
// TODO(rjeczalik): tolerate open failures - add failed names to
// AddDirError and notify users which names are not added to the tree.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen.go b/vendor/github.com/rjeczalik/notify/watcher_fen.go
index dd069f2a2..dfe77f2f1 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fen.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fen.go
@@ -33,14 +33,7 @@ type fen struct {
// watched is a data structure representing watched file/directory.
type watched struct {
- // p is a path to watched file/directory
- p string
- // fi provides information about watched file/dir
- fi os.FileInfo
- // eDir represents events watched directly
- eDir Event
- // eNonDir represents events watched indirectly
- eNonDir Event
+ trgWatched
}
// Stop implements trigger.
@@ -55,7 +48,7 @@ func (f *fen) Close() (err error) {
// NewWatched implements trigger.
func (*fen) NewWatched(p string, fi os.FileInfo) (*watched, error) {
- return &watched{p: p, fi: fi}, nil
+ return &watched{trgWatched{p: p, fi: fi}}, nil
}
// Record implements trigger.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
index 9062c17c7..7d9b97b65 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
@@ -12,8 +12,6 @@ import (
"sync/atomic"
)
-// TODO(rjeczalik): get rid of calls to canonical, it's tree responsibility
-
const (
failure = uint32(FSEventsMustScanSubDirs | FSEventsUserDropped | FSEventsKernelDropped)
filter = uint32(FSEventsCreated | FSEventsRemoved | FSEventsRenamed |
@@ -189,9 +187,6 @@ func newWatcher(c chan<- EventInfo) watcher {
}
func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) {
- if path, err = canonical(path); err != nil {
- return err
- }
if _, ok := fse.watches[path]; ok {
return errAlreadyWatched
}
@@ -211,9 +206,6 @@ func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) {
}
func (fse *fsevents) unwatch(path string) (err error) {
- if path, err = canonical(path); err != nil {
- return
- }
w, ok := fse.watches[path]
if !ok {
return errNotWatched
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
index 5be64632e..2248a1b12 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
@@ -26,9 +26,9 @@ import "C"
import (
"errors"
"os"
+ "runtime"
"sync"
"sync/atomic"
- "time"
"unsafe"
)
@@ -48,7 +48,7 @@ var wg sync.WaitGroup // used to wait until the runloop starts
// started and is ready via the wg. It also serves purpose of a dummy source,
// thanks to it the runloop does not return as it also has at least one source
// registered.
-var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{
+var source = C.CFRunLoopSourceCreate(refZero, 0, &C.CFRunLoopSourceContext{
perform: (C.CFRunLoopPerformCallBack)(C.gosource),
})
@@ -63,6 +63,10 @@ var (
func init() {
wg.Add(1)
go func() {
+ // There is exactly one run loop per thread. Lock this goroutine to its
+ // thread to ensure that it's not rescheduled on a different thread while
+ // setting up the run loop.
+ runtime.LockOSThread()
runloop = C.CFRunLoopGetCurrent()
C.CFRunLoopAddSource(runloop, source, C.kCFRunLoopDefaultMode)
C.CFRunLoopRun()
@@ -73,7 +77,6 @@ func init() {
//export gosource
func gosource(unsafe.Pointer) {
- time.Sleep(time.Second)
wg.Done()
}
@@ -159,8 +162,8 @@ func (s *stream) Start() error {
return nil
}
wg.Wait()
- p := C.CFStringCreateWithCStringNoCopy(nil, C.CString(s.path), C.kCFStringEncodingUTF8, nil)
- path := C.CFArrayCreate(nil, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
+ p := C.CFStringCreateWithCStringNoCopy(refZero, C.CString(s.path), C.kCFStringEncodingUTF8, refZero)
+ path := C.CFArrayCreate(refZero, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
ctx := C.FSEventStreamContext{}
ref := C.EventStreamCreate(&ctx, C.uintptr_t(s.info), path, C.FSEventStreamEventId(atomic.LoadUint64(&since)), latency, flags)
if ref == nilstream {
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go
new file mode 100644
index 000000000..0edd3782f
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go
@@ -0,0 +1,9 @@
+// Copyright (c) 2017 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build darwin,!kqueue,go1.10
+
+package notify
+
+const refZero = 0
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go
new file mode 100644
index 000000000..b81c3c185
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go
@@ -0,0 +1,14 @@
+// Copyright (c) 2017 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build darwin,!kqueue,cgo,!go1.10
+
+package notify
+
+/*
+#include <CoreServices/CoreServices.h>
+*/
+import "C"
+
+var refZero = (*C.struct___CFAllocator)(nil)
diff --git a/vendor/github.com/rjeczalik/notify/watcher_inotify.go b/vendor/github.com/rjeczalik/notify/watcher_inotify.go
index 3ceaa8f3a..d082baca0 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_inotify.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_inotify.go
@@ -13,14 +13,15 @@ import (
"runtime"
"sync"
"sync/atomic"
- "syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
// eventBufferSize defines the size of the buffer given to read(2) function. One
// should not depend on this value, since it was arbitrary chosen and may be
// changed in the future.
-const eventBufferSize = 64 * (syscall.SizeofInotifyEvent + syscall.PathMax + 1)
+const eventBufferSize = 64 * (unix.SizeofInotifyEvent + unix.PathMax + 1)
// consumersCount defines the number of consumers in producer-consumer based
// implementation. Each consumer is run in a separate goroutine and has read
@@ -43,7 +44,7 @@ type inotify struct {
fd int32 // inotify file descriptor
pipefd []int // pipe's read and write descriptors
epfd int // epoll descriptor
- epes []syscall.EpollEvent // epoll events
+ epes []unix.EpollEvent // epoll events
buffer [eventBufferSize]byte // inotify event buffer
wg sync.WaitGroup // wait group used to close main loop
c chan<- EventInfo // event dispatcher channel
@@ -56,13 +57,13 @@ func newWatcher(c chan<- EventInfo) watcher {
fd: invalidDescriptor,
pipefd: []int{invalidDescriptor, invalidDescriptor},
epfd: invalidDescriptor,
- epes: make([]syscall.EpollEvent, 0),
+ epes: make([]unix.EpollEvent, 0),
c: c,
}
runtime.SetFinalizer(i, func(i *inotify) {
i.epollclose()
if i.fd != invalidDescriptor {
- syscall.Close(int(i.fd))
+ unix.Close(int(i.fd))
}
})
return i
@@ -82,13 +83,13 @@ func (i *inotify) Rewatch(path string, _, newevent Event) error {
// one. If called for the first time, this function initializes inotify filesystem
// monitor and starts producer-consumers goroutines.
func (i *inotify) watch(path string, e Event) (err error) {
- if e&^(All|Event(syscall.IN_ALL_EVENTS)) != 0 {
+ if e&^(All|Event(unix.IN_ALL_EVENTS)) != 0 {
return errors.New("notify: unknown event")
}
if err = i.lazyinit(); err != nil {
return
}
- iwd, err := syscall.InotifyAddWatch(int(i.fd), path, encode(e))
+ iwd, err := unix.InotifyAddWatch(int(i.fd), path, encode(e))
if err != nil {
return
}
@@ -119,13 +120,13 @@ func (i *inotify) lazyinit() error {
i.Lock()
defer i.Unlock()
if atomic.LoadInt32(&i.fd) == invalidDescriptor {
- fd, err := syscall.InotifyInit()
+ fd, err := unix.InotifyInit1(unix.IN_CLOEXEC)
if err != nil {
return err
}
i.fd = int32(fd)
if err = i.epollinit(); err != nil {
- _, _ = i.epollclose(), syscall.Close(int(fd)) // Ignore errors.
+ _, _ = i.epollclose(), unix.Close(int(fd)) // Ignore errors.
i.fd = invalidDescriptor
return err
}
@@ -145,33 +146,33 @@ func (i *inotify) lazyinit() error {
// with inotify event queue and the read end of the pipe are added to epoll set.
// Note that `fd` member must be set before this function is called.
func (i *inotify) epollinit() (err error) {
- if i.epfd, err = syscall.EpollCreate1(0); err != nil {
+ if i.epfd, err = unix.EpollCreate1(0); err != nil {
return
}
- if err = syscall.Pipe(i.pipefd); err != nil {
+ if err = unix.Pipe(i.pipefd); err != nil {
return
}
- i.epes = []syscall.EpollEvent{
- {Events: syscall.EPOLLIN, Fd: i.fd},
- {Events: syscall.EPOLLIN, Fd: int32(i.pipefd[0])},
+ i.epes = []unix.EpollEvent{
+ {Events: unix.EPOLLIN, Fd: i.fd},
+ {Events: unix.EPOLLIN, Fd: int32(i.pipefd[0])},
}
- if err = syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil {
+ if err = unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil {
return
}
- return syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1])
+ return unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1])
}
// epollclose closes the file descriptor created by the call to epoll_create(2)
// and two file descriptors opened by pipe(2) function.
func (i *inotify) epollclose() (err error) {
if i.epfd != invalidDescriptor {
- if err = syscall.Close(i.epfd); err == nil {
+ if err = unix.Close(i.epfd); err == nil {
i.epfd = invalidDescriptor
}
}
for n, fd := range i.pipefd {
if fd != invalidDescriptor {
- switch e := syscall.Close(fd); {
+ switch e := unix.Close(fd); {
case e != nil && err == nil:
err = e
case e == nil:
@@ -187,10 +188,10 @@ func (i *inotify) epollclose() (err error) {
// one of the event's consumers. If pipe fd became ready, loop function closes
// all file descriptors opened by lazyinit method and returns afterwards.
func (i *inotify) loop(esch chan<- []*event) {
- epes := make([]syscall.EpollEvent, 1)
+ epes := make([]unix.EpollEvent, 1)
fd := atomic.LoadInt32(&i.fd)
for {
- switch _, err := syscall.EpollWait(i.epfd, epes, -1); err {
+ switch _, err := unix.EpollWait(i.epfd, epes, -1); err {
case nil:
switch epes[0].Fd {
case fd:
@@ -199,17 +200,17 @@ func (i *inotify) loop(esch chan<- []*event) {
case int32(i.pipefd[0]):
i.Lock()
defer i.Unlock()
- if err = syscall.Close(int(fd)); err != nil && err != syscall.EINTR {
+ if err = unix.Close(int(fd)); err != nil && err != unix.EINTR {
panic("notify: close(2) error " + err.Error())
}
atomic.StoreInt32(&i.fd, invalidDescriptor)
- if err = i.epollclose(); err != nil && err != syscall.EINTR {
+ if err = i.epollclose(); err != nil && err != unix.EINTR {
panic("notify: epollclose error " + err.Error())
}
close(esch)
return
}
- case syscall.EINTR:
+ case unix.EINTR:
continue
default: // We should never reach this line.
panic("notify: epoll_wait(2) error " + err.Error())
@@ -220,22 +221,22 @@ func (i *inotify) loop(esch chan<- []*event) {
// read reads events from an inotify file descriptor. It does not handle errors
// returned from read(2) function since they are not critical to watcher logic.
func (i *inotify) read() (es []*event) {
- n, err := syscall.Read(int(i.fd), i.buffer[:])
- if err != nil || n < syscall.SizeofInotifyEvent {
+ n, err := unix.Read(int(i.fd), i.buffer[:])
+ if err != nil || n < unix.SizeofInotifyEvent {
return
}
- var sys *syscall.InotifyEvent
- nmin := n - syscall.SizeofInotifyEvent
+ var sys *unix.InotifyEvent
+ nmin := n - unix.SizeofInotifyEvent
for pos, path := 0, ""; pos <= nmin; {
- sys = (*syscall.InotifyEvent)(unsafe.Pointer(&i.buffer[pos]))
- pos += syscall.SizeofInotifyEvent
+ sys = (*unix.InotifyEvent)(unsafe.Pointer(&i.buffer[pos]))
+ pos += unix.SizeofInotifyEvent
if path = ""; sys.Len > 0 {
endpos := pos + int(sys.Len)
path = string(bytes.TrimRight(i.buffer[pos:endpos], "\x00"))
pos = endpos
}
es = append(es, &event{
- sys: syscall.InotifyEvent{
+ sys: unix.InotifyEvent{
Wd: sys.Wd,
Mask: sys.Mask,
Cookie: sys.Cookie,
@@ -268,7 +269,7 @@ func (i *inotify) transform(es []*event) []*event {
var multi []*event
i.RLock()
for idx, e := range es {
- if e.sys.Mask&(syscall.IN_IGNORED|syscall.IN_Q_OVERFLOW) != 0 {
+ if e.sys.Mask&(unix.IN_IGNORED|unix.IN_Q_OVERFLOW) != 0 {
es[idx] = nil
continue
}
@@ -317,7 +318,7 @@ func encode(e Event) uint32 {
// can be nil when the event should not be passed on.
func decode(mask Event, e *event) (syse *event) {
if sysmask := uint32(mask) & e.sys.Mask; sysmask != 0 {
- syse = &event{sys: syscall.InotifyEvent{
+ syse = &event{sys: unix.InotifyEvent{
Wd: e.sys.Wd,
Mask: e.sys.Mask,
Cookie: e.sys.Cookie,
@@ -357,7 +358,7 @@ func (i *inotify) Unwatch(path string) (err error) {
return errors.New("notify: path " + path + " is already watched")
}
fd := atomic.LoadInt32(&i.fd)
- if _, err = syscall.InotifyRmWatch(int(fd), uint32(iwd)); err != nil {
+ if err = removeInotifyWatch(fd, iwd); err != nil {
return
}
i.Lock()
@@ -377,12 +378,12 @@ func (i *inotify) Close() (err error) {
return nil
}
for iwd := range i.m {
- if _, e := syscall.InotifyRmWatch(int(i.fd), uint32(iwd)); e != nil && err == nil {
+ if e := removeInotifyWatch(i.fd, iwd); e != nil && err == nil {
err = e
}
delete(i.m, iwd)
}
- switch _, errwrite := syscall.Write(i.pipefd[1], []byte{0x00}); {
+ switch _, errwrite := unix.Write(i.pipefd[1], []byte{0x00}); {
case errwrite != nil && err == nil:
err = errwrite
fallthrough
@@ -394,3 +395,11 @@ func (i *inotify) Close() (err error) {
}
return
}
+
+// if path was removed, notify already removed the watch and returns EINVAL error
+func removeInotifyWatch(fd int32, iwd int32) (err error) {
+ if _, err = unix.InotifyRmWatch(int(fd), uint32(iwd)); err != nil && err != unix.EINVAL {
+ return
+ }
+ return nil
+}
diff --git a/vendor/github.com/rjeczalik/notify/watcher_kqueue.go b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
index 6d500b700..22e3c2c4a 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
@@ -36,16 +36,9 @@ type kq struct {
// watched is a data structure representing watched file/directory.
type watched struct {
- // p is a path to watched file/directory.
- p string
+ trgWatched
// fd is a file descriptor for watched file/directory.
fd int
- // fi provides information about watched file/dir.
- fi os.FileInfo
- // eDir represents events watched directly.
- eDir Event
- // eNonDir represents events watched indirectly.
- eNonDir Event
}
// Stop implements trigger.
@@ -66,7 +59,10 @@ func (*kq) NewWatched(p string, fi os.FileInfo) (*watched, error) {
if err != nil {
return nil, err
}
- return &watched{fd: fd, p: p, fi: fi}, nil
+ return &watched{
+ trgWatched: trgWatched{p: p, fi: fi},
+ fd: fd,
+ }, nil
}
// Record implements trigger.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
index 5923bfdda..1494fcd79 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
@@ -284,16 +284,18 @@ func (r *readdcw) watch(path string, event Event, recursive bool) (err error) {
return
}
r.Lock()
+ defer r.Unlock()
if wd, ok = r.m[path]; ok {
- r.Unlock()
+ dbgprint("watch: exists already")
return
}
if wd, err = newWatched(r.cph, uint32(event), recursive, path); err != nil {
- r.Unlock()
return
}
r.m[path] = wd
- r.Unlock()
+ dbgprint("watch: new watch added")
+ } else {
+ dbgprint("watch: exists already")
}
return nil
}
@@ -337,33 +339,32 @@ func (r *readdcw) loop() {
continue
}
overEx := (*overlappedEx)(unsafe.Pointer(overlapped))
- if n == 0 {
- r.loopstate(overEx)
- } else {
+ if n != 0 {
r.loopevent(n, overEx)
if err = overEx.parent.readDirChanges(); err != nil {
// TODO: error handling
}
}
+ r.loopstate(overEx)
}
}
// TODO(pknap) : doc
func (r *readdcw) loopstate(overEx *overlappedEx) {
- filter := atomic.LoadUint32(&overEx.parent.parent.filter)
+ r.Lock()
+ defer r.Unlock()
+ filter := overEx.parent.parent.filter
if filter&onlyMachineStates == 0 {
return
}
if overEx.parent.parent.count--; overEx.parent.parent.count == 0 {
switch filter & onlyMachineStates {
case stateRewatch:
- r.Lock()
+ dbgprint("loopstate rewatch")
overEx.parent.parent.recreate(r.cph)
- r.Unlock()
case stateUnwatch:
- r.Lock()
+ dbgprint("loopstate unwatch")
delete(r.m, syscall.UTF16ToString(overEx.parent.pathw))
- r.Unlock()
case stateCPClose:
default:
panic(`notify: windows loopstate logic error`)
@@ -450,8 +451,8 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool
}
var wd *watched
r.Lock()
- if wd, err = r.nonStateWatched(path); err != nil {
- r.Unlock()
+ defer r.Unlock()
+ if wd, err = r.nonStateWatchedLocked(path); err != nil {
return
}
if wd.filter&(onlyNotifyChanges|onlyNGlobalEvents) != oldevent {
@@ -462,21 +463,19 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool
if err = wd.closeHandle(); err != nil {
wd.filter = oldevent
wd.recursive = recursive
- r.Unlock()
return
}
- r.Unlock()
return
}
// TODO : pknap
-func (r *readdcw) nonStateWatched(path string) (wd *watched, err error) {
+func (r *readdcw) nonStateWatchedLocked(path string) (wd *watched, err error) {
wd, ok := r.m[path]
if !ok || wd == nil {
err = errors.New(`notify: ` + path + ` path is unwatched`)
return
}
- if filter := atomic.LoadUint32(&wd.filter); filter&onlyMachineStates != 0 {
+ if wd.filter&onlyMachineStates != 0 {
err = errors.New(`notify: another re/unwatching operation in progress`)
return
}
@@ -497,17 +496,26 @@ func (r *readdcw) RecursiveUnwatch(path string) error {
func (r *readdcw) unwatch(path string) (err error) {
var wd *watched
r.Lock()
- if wd, err = r.nonStateWatched(path); err != nil {
- r.Unlock()
+ defer r.Unlock()
+ if wd, err = r.nonStateWatchedLocked(path); err != nil {
return
}
wd.filter |= stateUnwatch
if err = wd.closeHandle(); err != nil {
wd.filter &^= stateUnwatch
- r.Unlock()
return
}
- r.Unlock()
+ if _, attrErr := syscall.GetFileAttributes(&wd.pathw[0]); attrErr != nil {
+ for _, g := range wd.digrip {
+ if g != nil {
+ dbgprint("unwatch: posting")
+ if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil {
+ wd.filter &^= stateUnwatch
+ return
+ }
+ }
+ }
+ }
return
}
diff --git a/vendor/github.com/rjeczalik/notify/watcher_trigger.go b/vendor/github.com/rjeczalik/notify/watcher_trigger.go
index d079d59b0..78151f909 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_trigger.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_trigger.go
@@ -23,6 +23,7 @@
package notify
import (
+ "fmt"
"os"
"path/filepath"
"strings"
@@ -56,6 +57,19 @@ type trigger interface {
IsStop(n interface{}, err error) bool
}
+// trgWatched is a the base data structure representing watched file/directory.
+// The platform specific full data structure (watched) must embed this type.
+type trgWatched struct {
+ // p is a path to watched file/directory.
+ p string
+ // fi provides information about watched file/dir.
+ fi os.FileInfo
+ // eDir represents events watched directly.
+ eDir Event
+ // eNonDir represents events watched indirectly.
+ eNonDir Event
+}
+
// encode Event to native representation. Implementation is to be provided by
// platform specific implementation.
var encode func(Event, bool) int64
@@ -117,6 +131,9 @@ func (t *trg) Close() (err error) {
dbgprintf("trg: closing native watch failed: %q\n", e)
err = nonil(err, e)
}
+ if remaining := len(t.pthLkp); remaining != 0 {
+ err = nonil(err, fmt.Errorf("Not all watches were removed: len(t.pthLkp) == %v", len(t.pthLkp)))
+ }
t.Unlock()
return
}
@@ -175,7 +192,7 @@ func decode(o int64, w Event) (e Event) {
func (t *trg) watch(p string, e Event, fi os.FileInfo) error {
if err := t.singlewatch(p, e, dir, fi); err != nil {
if err != errAlreadyWatched {
- return nil
+ return err
}
}
if fi.IsDir() {
@@ -361,7 +378,7 @@ func (t *trg) singleunwatch(p string, direct mode) error {
}
if w.eNonDir|w.eDir != 0 {
mod := dir
- if w.eNonDir == 0 {
+ if w.eNonDir != 0 {
mod = ndir
}
if err := t.singlewatch(p, w.eNonDir|w.eDir, mod,