Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
arp242 committed Aug 6, 2022
1 parent c601f71 commit 1a30f16
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 49 deletions.
36 changes: 19 additions & 17 deletions fsnotify.go
Expand Up @@ -17,23 +17,6 @@ import (
"strings"
)

// These are the generalized file operations that can trigger a notification.
const (
Create Op = 1 << iota
Write
Remove
Rename
Chmod
)

// Common errors that can be reported by a watcher
var (
ErrNonExistentWatch = errors.New("can't remove non-existent watcher")
ErrEventOverflow = errors.New("fsnotify queue overflow")
ErrNotDirectory = errors.New("not a directory")
ErrRecursionUnsupported = errors.New("recursion not supported")
)

// Event represents a single file system notification.
type Event struct {
// Path to the file or directory.
Expand All @@ -53,6 +36,23 @@ type Event struct {
// Op describes a set of file operations.
type Op uint32

// These are the generalized file operations that can trigger a notification.
const (
Create Op = 1 << iota
Write
Remove
Rename
Chmod
)

// Common errors that can be reported by a watcher
var (
ErrNonExistentWatch = errors.New("can't remove non-existent watcher")
ErrEventOverflow = errors.New("fsnotify queue overflow")
ErrNotDirectory = errors.New("not a directory")
ErrRecursionUnsupported = errors.New("recursion not supported")
)

func (op Op) String() string {
var b strings.Builder
if op.Has(Create) {
Expand Down Expand Up @@ -90,6 +90,8 @@ func (e Event) String() string {

// findDirs finds all directories under path (return value *includes* path as
// the first entry).
//
// A symlink for a directory is not considered a directory.
func findDirs(path string) ([]string, error) {
dirs := make([]string, 0, 8)
err := filepath.WalkDir(path, func(root string, d fs.DirEntry, err error) error {
Expand Down
29 changes: 6 additions & 23 deletions inotify.go
Expand Up @@ -121,8 +121,8 @@ func (w *Watcher) Close() error {
// Add starts watching a file or directory.
//
// If the path is a directory then changes to that directory are watched
// non-recursively. If the path ends with "..." changes in the entire directory
// tree are watched. ErrNotDirectory is returned when using "..." on a file.
// non-recursively. If the path ends with "/..." changes in the entire directory
// tree are watched. ErrNotDirectory is returned when using "/..." on a file.
//
// Symlinks are not followed.
func (w *Watcher) Add(path string) error {
Expand Down Expand Up @@ -344,30 +344,13 @@ func (w *Watcher) readEvents() {
}
}

// Certain types of events can be "ignored" and not sent over the Events
// channel. Such as events marked ignore by the kernel, or MODIFY events
// against files that do not exist.
func (e *Event) ignoreLinux(mask uint32) bool {
// Ignore anything the inotify API says to ignore
if mask&unix.IN_IGNORED == unix.IN_IGNORED {
return true
}

// If the event is Create or Write, the file must exist, or the
// event will be suppressed.
// *Note*: this was put in place because it was seen that a Write
// event was sent after the Remove. This ignores the Write and
// assumes a Remove will come or has come if the file doesn't exist.
if e.Op&Create == Create || e.Op&Write == Write {
_, statErr := os.Lstat(e.Name)
return os.IsNotExist(statErr)
}
return false
}

// Check if path was added as a recursive watch ("dir/...").
//
// Returns the watch for the path, or nil.
func (w *Watcher) isRecursive(path string) *watch {
ww, ok := w.watches[path]
if !ok {
// path could be a file, so also check the Dir.
path = filepath.Dir(path)
ww, ok = w.watches[path]
if !ok {
Expand Down
22 changes: 13 additions & 9 deletions integration_test.go
Expand Up @@ -577,7 +577,7 @@ func TestRemove(t *testing.T) {
})
}

func TestRecursive(t *testing.T) {
func TestWatcherRecursive(t *testing.T) {
switch runtime.GOOS {
case "linux":
// Run test.
Expand Down Expand Up @@ -606,13 +606,13 @@ func TestRecursive(t *testing.T) {
// recursively add watches for any subdirectories that it contains).

tests := []testCase{
// Make a nested directory tree, then write some files there.
{"basic", func(t *testing.T, w *Watcher, tmp string) {
mkdirAll(t, tmp, "/one/two/three/four")
addWatch(t, w, tmp, "...")
addWatch(t, w, tmp, "/...")

// func(t *testing.T, tmp string) {
cat(t, "asd", tmp, "file.txt")
cat(t, "asd", tmp, "one/two/three/file.txt")
cat(t, "asd", tmp, "/file.txt")
cat(t, "asd", tmp, "/one/two/three/file.txt")
}, `
CREATE "/file.txt"
WRITE "/file.txt"
Expand All @@ -622,18 +622,19 @@ func TestRecursive(t *testing.T) {

{"add directory", func(t *testing.T, w *Watcher, tmp string) {
mkdirAll(t, tmp, "/one/two/three/four")
addWatch(t, w, tmp, "...")
addWatch(t, w, tmp, "/...")

mkdirAll(t, tmp, "one/two/new/dir")
touch(t, tmp, "one/two/new/file")
touch(t, tmp, "one/two/new/dir/file")
mkdirAll(t, tmp, "/one/two/new/dir")
touch(t, tmp, "/one/two/new/file")
touch(t, tmp, "/one/two/new/dir/file")
}, `
# TODO: don't see the new/dir being created.
CREATE "/one/two/new"
CREATE "/one/two/new/file"
CREATE "/one/two/new/dir/file"
`},

// Remove nested directory
{"remove directory", func(t *testing.T, w *Watcher, tmp string) {
mkdirAll(t, tmp, "/one/two/three/four")
addWatch(t, w, tmp, "...")
Expand All @@ -655,6 +656,7 @@ func TestRecursive(t *testing.T) {
REMOVE "/one/two"
`},

// Rename nested directory
{"rename directory", func(t *testing.T, w *Watcher, tmp string) {
mkdirAll(t, tmp, "/one/two/three/four")
addWatch(t, w, tmp, "...")
Expand All @@ -670,6 +672,8 @@ func TestRecursive(t *testing.T) {
CREATE "/one-rename/file"
CREATE "/one-rename/two/three/file"
`},

// TODO: rest that Remove doesn't keep watching stuff
}

for _, tt := range tests {
Expand Down

0 comments on commit 1a30f16

Please sign in to comment.