diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-08-28 20:42:46 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-08-28 20:42:46 -0600 |
commit | 3c237531f5067340e34b01c7f7ea45fa55c39657 (patch) | |
tree | e6dd9be0682046ef755641a2cd49a0120ea0ea80 /src/inotify/inotify.go | |
parent | 4f16ef5707daf4acd74a07b665d1d67ab97c1f44 (diff) |
switch to my own inotify bindings, the golang.org/x/exp bindings are crap
Diffstat (limited to 'src/inotify/inotify.go')
-rw-r--r-- | src/inotify/inotify.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/inotify/inotify.go b/src/inotify/inotify.go new file mode 100644 index 0000000..976bdae --- /dev/null +++ b/src/inotify/inotify.go @@ -0,0 +1,94 @@ +package inotify + +import ( + "errors" + "syscall" + "unsafe" +) + +var InotifyAlreadyClosedError error = errors.New("inotify instance already closed") + +type Inotify struct { + fd Cint + isClosed bool + + fullbuff [4096]byte + buff []byte +} + +type Event struct { + Wd Cint /* Watch descriptor */ + Mask Mask /* Mask describing event */ + Cookie uint32 /* Unique cookie associating related events (for rename(2)) */ + Name *string /* Optional name */ +} + +func InotifyInit() (*Inotify, error) { + fd, err := inotify_init() + o := Inotify{ + fd: Cint(fd), + isClosed: false, + } + o.buff = o.fullbuff[:] + return &o, err +} + +func InotifyInit1(flags Cint) (*Inotify, error) { + fd, err := inotify_init1(flags) + o := Inotify{ + fd: Cint(fd), + isClosed: false, + } + o.buff = o.fullbuff[:] + return &o, err +} + +func (o *Inotify) AddWatch(path string, mask Mask) (Cint, error) { + if o.isClosed { + return -1, InotifyAlreadyClosedError + } + return inotify_add_watch(o.fd, path, uint32(mask)) +} + +func (o *Inotify) RmWatch(wd Cint) error { + if o.isClosed { + return InotifyAlreadyClosedError + } + return inotify_rm_watch(o.fd, wd) +} + +func (o *Inotify) Close() error { + if o.isClosed { + return InotifyAlreadyClosedError + } + o.isClosed = true + return sysclose(o.fd) +} + +func (o *Inotify) Read() (*Event, error) { + if len(o.buff) == 0 { + if o.isClosed { + return nil, InotifyAlreadyClosedError + } + len, err := sysread(o.fd, o.buff) + if len == 0 { + return nil, o.Close() + } else if len <= 0 { + return nil, err + } + o.buff = o.fullbuff[0:len] + } + raw := (*syscall.InotifyEvent)(unsafe.Pointer(&o.buff[0])) + var ret Event + ret.Wd = Cint(raw.Wd) + ret.Mask = Mask(raw.Mask) + ret.Cookie = raw.Cookie + ret.Name = nil + if raw.Len > 0 { + bytes := (*[syscall.NAME_MAX]byte)(unsafe.Pointer(&o.buff[syscall.SizeofInotifyEvent])) + name := string(bytes[:raw.Len-1]) + ret.Name = &name + } + o.buff = o.buff[0 : syscall.SizeofInotifyEvent+raw.Len] + return &ret, nil +} |