Copied Inotify watcher with addition of ModMask.
This commit is contained in:
parent
80d618347e
commit
3da4bd9aed
85
pkg/watcher/linux.go
Normal file
85
pkg/watcher/linux.go
Normal file
@ -0,0 +1,85 @@
|
||||
package watcher
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
CrDelMask uint32 = syscall.IN_CREATE | syscall.IN_DELETE
|
||||
ModMask uint32 = syscall.IN_MODIFY
|
||||
)
|
||||
|
||||
const inotifyCount = 16
|
||||
|
||||
type InotifyWatcher struct {
|
||||
fd int
|
||||
wds []int
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewInotifyWatcher() (w *InotifyWatcher, err error) {
|
||||
w = &InotifyWatcher{closed: false}
|
||||
|
||||
w.fd, err = syscall.InotifyInit()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialise inotify watcher")
|
||||
}
|
||||
|
||||
w.wds = make([]int, 0)
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (w *InotifyWatcher) AddWatch(path string, mask uint32) error {
|
||||
wd, err := syscall.InotifyAddWatch(w.fd, path, mask)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to set %s on watch", path)
|
||||
}
|
||||
|
||||
w.wds = append(w.wds, wd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WatchForMask checking for events from mask and returns inotify mask to channel.
|
||||
func (w *InotifyWatcher) WatchForMask(fired chan uint32, mask uint32) {
|
||||
go func() {
|
||||
for !w.closed {
|
||||
buffer := make([]byte, syscall.SizeofInotifyEvent*inotifyCount)
|
||||
n, err := syscall.Read(w.fd, buffer)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
if n < syscall.SizeofInotifyEvent {
|
||||
continue
|
||||
}
|
||||
|
||||
for offset := 0; offset < len(buffer); offset += syscall.SizeofInotifyEvent {
|
||||
event := (*syscall.InotifyEvent)(unsafe.Pointer(&buffer[offset]))
|
||||
if event.Mask&mask > 0 {
|
||||
fired <- event.Mask
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (w *InotifyWatcher) Close() error {
|
||||
for _, wd := range w.wds {
|
||||
if _, err := syscall.InotifyRmWatch(w.fd, uint32(wd)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := syscall.Close(w.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.closed = true
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user