aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/rjeczalik/notify/watcher_fen.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/rjeczalik/notify/watcher_fen.go')
-rw-r--r--vendor/github.com/rjeczalik/notify/watcher_fen.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen.go b/vendor/github.com/rjeczalik/notify/watcher_fen.go
new file mode 100644
index 000000000..60e9a36da
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/watcher_fen.go
@@ -0,0 +1,170 @@
+// 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 solaris
+
+package notify
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+)
+
+// newTrigger returns implementation of trigger.
+func newTrigger(pthLkp map[string]*watched) trigger {
+ return &fen{
+ pthLkp: pthLkp,
+ cf: newCfen(),
+ }
+}
+
+// fen is a structure implementing trigger for FEN.
+type fen struct {
+ // p is a FEN port identifier
+ p int
+ // pthLkp is a structure mapping monitored files/dir with data about them,
+ // shared with parent trg structure
+ pthLkp map[string]*watched
+ // cf wraps C operations for FEN
+ cf cfen
+}
+
+// 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
+}
+
+// Stop implements trigger.
+func (f *fen) Stop() error {
+ return f.cf.port_alert(f.p)
+}
+
+// Close implements trigger.
+func (f *fen) Close() (err error) {
+ return syscall.Close(f.p)
+}
+
+// NewWatched implements trigger.
+func (*fen) NewWatched(p string, fi os.FileInfo) (*watched, error) {
+ return &watched{p: p, fi: fi}, nil
+}
+
+// Record implements trigger.
+func (f *fen) Record(w *watched) {
+ f.pthLkp[w.p] = w
+}
+
+// Del implements trigger.
+func (f *fen) Del(w *watched) {
+ delete(f.pthLkp, w.p)
+}
+
+func inter2pe(n interface{}) PortEvent {
+ pe, ok := n.(PortEvent)
+ if !ok {
+ panic(fmt.Sprintf("fen: type should be PortEvent, %T instead", n))
+ }
+ return pe
+}
+
+// Watched implements trigger.
+func (f *fen) Watched(n interface{}) (*watched, int64, error) {
+ pe := inter2pe(n)
+ fo, ok := pe.PortevObject.(*FileObj)
+ if !ok || fo == nil {
+ panic(fmt.Sprintf("fen: type should be *FileObj, %T instead", fo))
+ }
+ w, ok := f.pthLkp[fo.Name]
+ if !ok {
+ return nil, 0, errNotWatched
+ }
+ return w, int64(pe.PortevEvents), nil
+}
+
+// init initializes FEN.
+func (f *fen) Init() (err error) {
+ f.p, err = f.cf.port_create()
+ return
+}
+
+func fi2fo(fi os.FileInfo, p string) FileObj {
+ st, ok := fi.Sys().(*syscall.Stat_t)
+ if !ok {
+ panic(fmt.Sprintf("fen: type should be *syscall.Stat_t, %T instead", st))
+ }
+ return FileObj{Name: p, Atim: st.Atim, Mtim: st.Mtim, Ctim: st.Ctim}
+}
+
+// Unwatch implements trigger.
+func (f *fen) Unwatch(w *watched) error {
+ return f.cf.port_dissociate(f.p, FileObj{Name: w.p})
+}
+
+// Watch implements trigger.
+func (f *fen) Watch(fi os.FileInfo, w *watched, e int64) error {
+ return f.cf.port_associate(f.p, fi2fo(fi, w.p), int(e))
+}
+
+// Wait implements trigger.
+func (f *fen) Wait() (interface{}, error) {
+ var (
+ pe PortEvent
+ err error
+ )
+ err = f.cf.port_get(f.p, &pe)
+ return pe, err
+}
+
+// IsStop implements trigger.
+func (f *fen) IsStop(n interface{}, err error) bool {
+ return err == syscall.EBADF || inter2pe(n).PortevSource == srcAlert
+}
+
+func init() {
+ encode = func(e Event) (o int64) {
+ // Create event is not supported by FEN. Instead FileModified event will
+ // be registered. If this event will be reported on dir which is to be
+ // monitored for Create, dir will be rescanned and Create events will
+ // be generated and returned for new files. In case of files,
+ // if not requested FileModified event is reported, it will be ignored.
+ if e&Create != 0 {
+ o = (o &^ int64(Create)) | int64(FileModified)
+ }
+ if e&Write != 0 {
+ o = (o &^ int64(Write)) | int64(FileModified)
+ }
+ // Following events are 'exception events' and as such cannot be requested
+ // explicitly for monitoring or filtered out. If the will be reported
+ // by FEN and not subscribed with by user, they will be filtered out by
+ // watcher's logic.
+ o &= int64(^Rename & ^Remove &^ FileDelete &^ FileRenameTo &^
+ FileRenameFrom &^ Unmounted &^ MountedOver)
+ return
+ }
+ nat2not = map[Event]Event{
+ FileModified: Write,
+ FileRenameFrom: Rename,
+ FileDelete: Remove,
+ FileAccess: Event(0),
+ FileAttrib: Event(0),
+ FileRenameTo: Event(0),
+ FileTrunc: Event(0),
+ FileNoFollow: Event(0),
+ Unmounted: Event(0),
+ MountedOver: Event(0),
+ }
+ not2nat = map[Event]Event{
+ Write: FileModified,
+ Rename: FileRenameFrom,
+ Remove: FileDelete,
+ }
+}