Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
fsnotify is a Go library to provide cross-platform filesystem notifications on
Windows, Linux, macOS, BSD, and illumos.

Go 1.17 or newer is required; the full documentation is at
https://pkg.go.dev/github.com/fsnotify/fsnotify
Fork of the original [fsnotify](https://github.com/fsnotify/fsnotify) library that enables recursive watching.
Because of the current implementation limitations, the only supported platforms are updated in the table below.

---

Platform support:

| Backend | OS | Status |
| :-------------------- | :--------- | :------------------------------------------------------------------------ |
| :-------------------- | :--------- |:--------------------------------------------------------------------------|
| inotify | Linux | Supported |
| kqueue | BSD, macOS | Supported |
| kqueue | BSD, macOS | [Not Yet](https://github.com/fsnotify/fsnotify/issues/18) |
| ReadDirectoryChangesW | Windows | Supported |
| FEN | illumos | Supported |
| FEN | illumos | [Not Yet](https://github.com/fsnotify/fsnotify/issues/18) |
| fanotify | Linux 5.9+ | [Not yet](https://github.com/fsnotify/fsnotify/issues/114) |
| FSEvents | macOS | [Needs support in x/sys/unix][fsevents] |
| USN Journals | Windows | [Needs support in x/sys/windows][usn] |
Expand All @@ -35,7 +32,7 @@ package main
import (
"log"

"github.com/fsnotify/fsnotify"
"github.com/e2b-dev/fsnotify"
)

func main() {
Expand Down Expand Up @@ -92,8 +89,7 @@ FAQ
No, not unless you are watching the location it was moved to.

### Are subdirectories watched?
No, you must add watches for any directory you want to watch (a recursive
watcher is on the roadmap: [#18]).
Yes. The provided path has to end with "..." to watch subdirectories.

[#18]: https://github.com/fsnotify/fsnotify/issues/18

Expand Down
2 changes: 1 addition & 1 deletion backend_fen.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"sync"
"time"

"github.com/fsnotify/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal"
"golang.org/x/sys/unix"
)

Expand Down
50 changes: 49 additions & 1 deletion backend_inotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"time"
"unsafe"

"github.com/fsnotify/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -248,6 +248,17 @@ func (w *inotify) AddWith(path string, opts ...addOpt) error {
w.sendEvent(Event{Name: root, Op: Create})
}

// If there's a dir for which we don't have read permissions,
// skip it silently. If it's the root directory itself, return an error.
_, infoErr := d.Info()
if infoErr != nil && errors.Is(infoErr, os.ErrPermission) {
if root == path {
return fmt.Errorf("fsnotify: not a readable directory: %q", path)
}

return filepath.SkipDir // Skip this directory silently.
}

wf := flagRecurse
if root == path {
wf |= flagByUser
Expand Down Expand Up @@ -510,6 +521,43 @@ func (w *inotify) handleEvent(inEvent *unix.InotifyEvent, buf *[65536]byte, offs
w.watches.wd[k] = ww
}
}
} else {
// Register a newly created dir tree
// This is for "mkdir -p one/two/three".
// Usually all those directories will be created before we can set up
// watchers on the subdirectories, so only "one" would be sent
// as a Create event and not "one/two" and "one/two/three"
// (inotifywait -r has the same problem).
err = filepath.WalkDir(ev.Name, func(curDir string, d fs.DirEntry, err error) error {
if err != nil {
return err
}

if ev.Name != curDir {
// Send artificial create event.
// We don't know what has really happened.

// Send the previous event first to maintain proper ordering, then create a new event for the current directory
// The function expects to return only one event, so we need to send the previous event first and then create a new one
w.sendEvent(ev)
ev = w.newEvent(curDir, unix.IN_CREATE, 0)
}

// If there's a dir for which we don't have read permissions,
// skip it silently. If it's the root directory itself, return an error.
_, infoErr := d.Info()
if infoErr != nil && errors.Is(infoErr, os.ErrPermission) {
return filepath.SkipDir // Skip this directory silently.
}

if d.IsDir() {
return w.register(curDir, watch.flags, flagRecurse)
}
return nil
})
if !w.sendError(err) {
return Event{}, false
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend_kqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"sync"
"time"

"github.com/fsnotify/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal"
"golang.org/x/sys/unix"
)

Expand Down
2 changes: 1 addition & 1 deletion backend_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"time"
"unsafe"

"github.com/fsnotify/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal"
"golang.org/x/sys/windows"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/fsnotify/dedup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"
"time"

"github.com/fsnotify/fsnotify"
"github.com/e2b-dev/fsnotify"
)

// Depending on the system, a single "write" can generate many Write events; for
Expand Down
2 changes: 1 addition & 1 deletion cmd/fsnotify/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"os"
"path/filepath"

"github.com/fsnotify/fsnotify"
"github.com/e2b-dev/fsnotify"
)

// Watch one or more files, but instead of watching the file directly it watches
Expand Down
2 changes: 1 addition & 1 deletion cmd/fsnotify/watch.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package main

import "github.com/fsnotify/fsnotify"
import "github.com/e2b-dev/fsnotify"

// This is the most basic example: it prints events to the terminal as we
// receive them.
Expand Down
7 changes: 4 additions & 3 deletions fsnotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,13 @@ func withOps(op Op) addOpt {
return func(opt *withOpts) { opt.op = op }
}

// "Internal" option for recursive watches on inotify.
func withCreate() addOpt {
// WithCreate "Internal" option for recursive watches on inotify.
func WithCreate() addOpt {
return func(opt *withOpts) { opt.sendCreate = true }
}

var enableRecurse = false
// Enable recursive folder watching
var enableRecurse = true

// Check if this path is recursive (ends with "/..." or "\..."), and return the
// path with the /... stripped.
Expand Down
2 changes: 1 addition & 1 deletion fsnotify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"testing"
"time"

"github.com/fsnotify/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal"
)

func init() {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/fsnotify/fsnotify
module github.com/e2b-dev/fsnotify

go 1.19

Expand Down
4 changes: 2 additions & 2 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
"testing"
"time"

"github.com/fsnotify/fsnotify/internal"
"github.com/fsnotify/fsnotify/internal/ztest"
"github.com/e2b-dev/fsnotify/internal"
"github.com/e2b-dev/fsnotify/internal/ztest"
)

// We wait a little bit after most commands; gives the system some time to sync
Expand Down
Loading