-
Notifications
You must be signed in to change notification settings - Fork 5
/
event.go
138 lines (118 loc) · 5.13 KB
/
event.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//go:build linux
// +build linux
package gonotify
import (
"fmt"
"strings"
"syscall"
)
const (
IN_ACCESS = uint32(syscall.IN_ACCESS) // File was accessed
IN_ATTRIB = uint32(syscall.IN_ATTRIB) // Metadata changed
IN_CLOSE_WRITE = uint32(syscall.IN_CLOSE_WRITE) // File opened for writing was closed.
IN_CLOSE_NOWRITE = uint32(syscall.IN_CLOSE_NOWRITE) // File or directory not opened for writing was closed.
IN_CREATE = uint32(syscall.IN_CREATE) // File/directory created in watched directory
IN_DELETE = uint32(syscall.IN_DELETE) // File/directory deleted from watched directory.
IN_DELETE_SELF = uint32(syscall.IN_DELETE_SELF) // Watched file/directory was itself deleted.
IN_MODIFY = uint32(syscall.IN_MODIFY) // File was modified
IN_MOVE_SELF = uint32(syscall.IN_MOVE_SELF) // Watched file/directory was itself moved.
IN_MOVED_FROM = uint32(syscall.IN_MOVED_FROM) // Generated for the directory containing the old filename when a file is renamed.
IN_MOVED_TO = uint32(syscall.IN_MOVED_TO) // Generated for the directory containing the new filename when a file is renamed.
IN_OPEN = uint32(syscall.IN_OPEN) // File or directory was opened.
IN_ALL_EVENTS = uint32(syscall.IN_ALL_EVENTS) // bit mask of all of the above events.
IN_MOVE = uint32(syscall.IN_MOVE) // Equates to IN_MOVED_FROM | IN_MOVED_TO.
IN_CLOSE = uint32(syscall.IN_CLOSE) // Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE.
/* The following further bits can be specified in mask when calling Inotify.AddWatch() */
IN_DONT_FOLLOW = uint32(syscall.IN_DONT_FOLLOW) // Don't dereference pathname if it is a symbolic link.
IN_EXCL_UNLINK = uint32(syscall.IN_EXCL_UNLINK) // Don't generate events for children if they have been unlinked from the directory.
IN_MASK_ADD = uint32(syscall.IN_MASK_ADD) // Add (OR) the events in mask to the watch mask
IN_ONESHOT = uint32(syscall.IN_ONESHOT) // Monitor the filesystem object corresponding to pathname for one event, then remove from watch list.
IN_ONLYDIR = uint32(syscall.IN_ONLYDIR) // Watch pathname only if it is a directory.
/* The following bits may be set in the mask field returned by Inotify.Read() */
IN_IGNORED = uint32(syscall.IN_IGNORED) // Watch was removed explicitly or automatically
IN_ISDIR = uint32(syscall.IN_ISDIR) // Subject of this event is a directory.
IN_Q_OVERFLOW = uint32(syscall.IN_Q_OVERFLOW) // Event queue overflowed (wd is -1 for this event).
IN_UNMOUNT = uint32(syscall.IN_UNMOUNT) // Filesystem containing watched object was unmounted.
)
var in_mapping = map[uint32]string{
IN_ACCESS: "IN_ACCESS",
IN_ATTRIB: "IN_ATTRIB",
IN_CLOSE_WRITE: "IN_CLOSE_WRITE",
IN_CLOSE_NOWRITE: "IN_CLOSE_NOWRITE",
IN_CREATE: "IN_CREATE",
IN_DELETE: "IN_DELETE",
IN_DELETE_SELF: "IN_DELETE_SELF",
IN_MODIFY: "IN_MODIFY",
IN_MOVE_SELF: "IN_MOVE_SELF",
IN_MOVED_FROM: "IN_MOVED_FROM",
IN_MOVED_TO: "IN_MOVED_TO",
IN_OPEN: "IN_OPEN",
IN_IGNORED: "IN_IGNORED",
IN_ISDIR: "IN_ISDIR",
IN_Q_OVERFLOW: "IN_Q_OVERFLOW",
IN_UNMOUNT: "IN_UNMOUNT",
}
func InMaskToString(in_mask uint32) string {
sb := &strings.Builder{}
divide := false
for mask, str := range in_mapping {
if in_mask&mask == mask {
if divide {
sb.WriteString("|")
}
sb.WriteString(str)
divide = true
}
}
return sb.String()
}
// InotifyEvent is the go representation of inotify_event found in sys/inotify.h
type InotifyEvent struct {
// Watch descriptor
Wd int
// File or directory name
Name string
// Contains bits that describe the event that occurred
Mask uint32
// Usually 0, but if events (like IN_MOVED_FROM and IN_MOVED_TO) are linked then they will have equal cookie
Cookie uint32
}
func (i InotifyEvent) GoString() string {
return fmt.Sprintf("gonotify.InotifyEvent{Wd=%#v, Name=%s, Cookie=%#v, Mask=%#v=%s}", i.Wd, i.Name, i.Cookie, i.Mask, InMaskToString(i.Mask))
}
func (i InotifyEvent) String() string {
return fmt.Sprintf("{Wd=%d, Name=%s, Cookie=%d, Mask=%s}", i.Wd, i.Name, i.Cookie, InMaskToString(i.Mask))
}
// IsAny returns true if any of the in_mask is set in the event
func (i InotifyEvent) IsAny(in_mask ...uint32) bool {
for _, mask := range in_mask {
if i.Mask&mask == mask {
return true
}
}
return false
}
// IsAll returns true if all the in_masks is set in the event
func (i InotifyEvent) IsAll(in_mask ...uint32) bool {
for _, mask := range in_mask {
if i.Mask&mask != mask {
return false
}
}
return true
}
func (i InotifyEvent) Is(in_mask uint32) bool {
return i.Mask&in_mask == in_mask
}
// FileEvent is the wrapper around InotifyEvent with additional Eof marker. Reading from
// FileEvents from DirWatcher.C or FileWatcher.C may end with Eof when underlying inotify is closed
type FileEvent struct {
InotifyEvent
Eof bool
}
func (f FileEvent) GoString() string {
return fmt.Sprintf("gonotify.FileEvent{InotifyEvent=%#v, Eof=%#v}", f.InotifyEvent, f.Eof)
}
func (f FileEvent) String() string {
return fmt.Sprintf("{InotifyEvent=%s, Eof=%v}", f.InotifyEvent, f.Eof)
}