-
-
Notifications
You must be signed in to change notification settings - Fork 53
/
kqueue.go
89 lines (77 loc) · 1.85 KB
/
kqueue.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// +build freebsd netbsd openbsd dragonfly darwin
// +build amd64 arm64
package immortal
import "syscall"
// WatchDir check for changes on a directory via Kqueue EVFILT_VNODE
func WatchDir(dir string, ch chan<- string) error {
watchfd, err := syscall.Open(dir, openModeDir, 0700)
if err != nil {
return err
}
kq, err := syscall.Kqueue()
if err != nil {
syscall.Close(watchfd)
return err
}
ev1 := syscall.Kevent_t{
Ident: uint64(watchfd),
Filter: syscall.EVFILT_VNODE,
Flags: syscall.EV_ADD | syscall.EV_ENABLE | syscall.EV_CLEAR,
Fflags: syscall.NOTE_WRITE | syscall.NOTE_ATTRIB,
Data: 0,
}
for {
// create kevent
kevents := []syscall.Kevent_t{ev1}
n, err := syscall.Kevent(kq, kevents, kevents, nil)
if err != nil {
syscall.Close(watchfd)
return err
}
// wait for an event
for len(kevents) > 0 {
if n > 0 {
ch <- dir
}
// Move to next event
kevents = kevents[1:]
}
}
}
// WatchFile check for changes on a file via kqueue EVFILT_VNODE
func WatchFile(f string, ch chan<- string) error {
watchfd, err := syscall.Open(f, openModeFile, 0700)
if err != nil {
return err
}
kq, err := syscall.Kqueue()
if err != nil {
syscall.Close(watchfd)
return err
}
ev1 := syscall.Kevent_t{
Ident: uint64(watchfd),
Filter: syscall.EVFILT_VNODE,
Flags: syscall.EV_ADD | syscall.EV_ENABLE | syscall.EV_ONESHOT,
Fflags: syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_LINK | syscall.NOTE_RENAME | syscall.NOTE_REVOKE,
Data: 0,
}
// create kevent
kevents := []syscall.Kevent_t{ev1}
n, err := syscall.Kevent(kq, kevents, kevents, nil)
if err != nil {
syscall.Close(watchfd)
return err
}
// wait for an event
for len(kevents) > 0 {
if n > 0 {
// do something
}
// Move to next event
kevents = kevents[1:]
}
syscall.Close(watchfd)
ch <- f
return nil
}