-# File system notifications for Go
+fsnotify is a Go library to provide cross-platform filesystem notifications on
+Windows, Linux, macOS, and BSD systems.
-[](https://pkg.go.dev/github.com/fsnotify/fsnotify) [](https://goreportcard.com/report/github.com/fsnotify/fsnotify)
+fsnotify requires Go 1.16 or newer.
-## Cross platform
+API docs: https://pkg.go.dev/github.com/fsnotify/fsnotify
-`fsnotify` supports Windows, Linux, BSD and macOS with a common API.
+Platform support:
-| Adapter | OS | Status |
-| --------------------- | -------------------------| -------------------------------------------------------------|
-| inotify | Linux 2.6.32+, Android\* | Supported |
-| kqueue | BSD, macOS, iOS\* | Supported |
-| ReadDirectoryChangesW | Windows | Supported |
-| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
-| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) |
-| fanotify | Linux 2.6.37+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) |
-| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
-| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
+| Adapter | OS | Status |
+| --------------------- | ---------------| -------------------------------------------------------------|
+| inotify | Linux 2.6.32+ | Supported |
+| kqueue | BSD, macOS | Supported |
+| ReadDirectoryChangesW | Windows | Supported |
+| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
+| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) |
+| fanotify | Linux 2.6.37+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) |
+| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
+| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
-\* Android and iOS are untested.
+Linux and macOS should include Android and iOS, but these are currently untested.
-fsnotify requires Go 1.16 or newer. Please see
-[the documentation](https://pkg.go.dev/github.com/fsnotify/fsnotify)
-and consult the [FAQ](#faq) for usage information.
-
-NOTE: fsnotify utilizes
-[`golang.org/x/sys`](https://pkg.go.dev/golang.org/x/sys) rather than
-[`syscall`](https://pkg.go.dev/syscall) from the standard library.
-
-## API stability
-
-fsnotify is a fork of [howeyc/fsnotify](https://github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA).
-
-All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/).
-
-## Usage
+Usage
+-----
+A basic example:
```go
package main
}
}()
- err = watcher.Add("/tmp/foo")
+ err = watcher.Add("/tmp")
if err != nil {
log.Fatal(err)
}
}
```
-A slightly more expansive example can be found in [cmd/fsnotify](cmd/fsnotify), which can be run with:
-
- # Watch the current directory (not recursive).
- $ go run ./cmd/fsnotify .
-
-## Contributing
-
-Please refer to [CONTRIBUTING][] before opening an issue or pull request.
-
-## FAQ
-
-**When a file is moved to another directory is it still being watched?**
+A slightly more expansive example can be found in [cmd/fsnotify](cmd/fsnotify),
+which can be run with:
-No (it shouldn't be, unless you are watching where it was moved to).
+ # Watch the current directory (not recursive).
+ $ go run ./cmd/fsnotify .
-**When I watch a directory, are all subdirectories watched as well?**
+FAQ
+---
+### Will a file still be watched when it's moved to another directory?
+No, not unless you are watching the location it was moved to.
-No, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap [#18][]).
+### Are all subdirectories watched too?
+No, you must add watches for any directory you want to watch (a recursive
+watcher is on the roadmap: [#18]).
-**Do I have to watch the Error and Event channels in a separate goroutine?**
+[#18]: https://github.com/fsnotify/fsnotify/issues/18
-As of now, yes. Looking into making this single-thread friendly (see [howeyc #7][#7])
+### Do I have to watch the Error and Event channels in a separate goroutine?
+As of now, yes.
-**Why am I receiving multiple events for the same file on macOS?**
+### Why don't notifications work with NFS, SMB, or FUSE?
+fsnotify requires support from underlying OS to work. The current NFS and SMB
+protocols does not provide network level support for file notifications.
-Spotlight indexing on macOS can result in multiple events (see
-[howeyc #62][#62]). A temporary workaround is to add your folder(s) to the
-*Spotlight Privacy settings* until we have a native FSEvents implementation (see
-[#11][]).
+Platform-specific notes
+-----------------------
+### Linux
+When a file is removed a REMOVE event won't be emitted until all file
+descriptors are closed. It will emit a CHMOD though:
-**How many files can be watched at once?**
+ fp := os.Open("file")
+ os.Remove("file") // CHMOD
+ fp.Close() // REMOVE
-There are OS-specific limits as to how many watches can be created:
+Linux: the `fs.inotify.max_user_watches` sysctl variable specifies the upper
+limit for the number of watches per user, and `fs.inotify.max_user_instances`
+specifies the maximum number of inotify instances per user. Every Watcher you
+create is an "instance", and every path you add is a "watch".
-* Linux: the `fs.inotify.max_user_watches` sysctl variable specifies the upper
- limit for the number of watches per user, and `fs.inotify.max_user_instances`
- specifies the maximum number of inotify instances per user. Every Watcher you
- create is an "instance", and every path you add is a "watch".
+These are also exposed in /proc as `/proc/sys/fs/inotify/max_user_watches` and
+`/proc/sys/fs/inotify/max_user_instances`
- These are also exposed in /proc as `/proc/sys/fs/inotify/max_user_watches` and
- `/proc/sys/fs/inotify/max_user_instances`
+To increase them you can use `sysctl` or write the value to proc file:
- To increase them you can use `sysctl` or write the value to proc file:
+ # The default values on Linux 5.18
+ sysctl fs.inotify.max_user_watches=124983
+ sysctl fs.inotify.max_user_instances=128
- # The default values on Linux 5.18
- sysctl fs.inotify.max_user_watches=124983
- sysctl fs.inotify.max_user_instances=128
+To make the changes persist on reboot edit `/etc/sysctl.conf` or
+`/usr/lib/sysctl.d/50-default.conf` (some systemd systems):
- To make the changes persist on reboot edit `/etc/sysctl.conf` or
- `/usr/lib/sysctl.d/50-default.conf` (some systemd systems):
+ fs.inotify.max_user_watches=124983
+ fs.inotify.max_user_instances=128
- fs.inotify.max_user_watches=124983
- fs.inotify.max_user_instances=128
+Reaching the limit will result in a "no space left on device" or "too many open
+files" error.
- Reaching the limit will result in a "no space left on device" or "too many
- open files" error.
+### kqueue (macOS, all BSD systems)
+kqueue requires opening a file descriptor for every file that's being watched;
+so if you're watching a directory with five files then that's six file
+descriptors. You will run in to your system's "max open files" limit faster on
+these platforms.
-* BSD / macOS: sysctl variables `kern.maxfiles` and `kern.maxfilesperproc`,
- reaching these limits results in a "too many open files" error.
+The sysctl variables `kern.maxfiles` and `kern.maxfilesperproc` can be used to
+control the maximum number of open files.
-**Why don't notifications work with NFS, SMB, or filesystem in userspace (FUSE)?**
+### macOS
+Spotlight indexing on macOS can result in multiple events (see [#15]). A temporary
+workaround is to add your folder(s) to the *Spotlight Privacy settings* until we
+have a native FSEvents implementation (see [#11]).
-fsnotify requires support from underlying OS to work. The current NFS and SMB
-protocols does not provide network level support for file notifications.
-
-[#62]: https://github.com/howeyc/fsnotify/issues/62
-[#18]: https://github.com/fsnotify/fsnotify/issues/18
[#11]: https://github.com/fsnotify/fsnotify/issues/11
-[#7]: https://github.com/howeyc/fsnotify/issues/7
-
-[contributing]: https://github.com/fsnotify/fsnotify/blob/main/CONTRIBUTING.md
-
-## Related Projects
+[#15]: https://github.com/fsnotify/fsnotify/issues/15
-* [notify](https://github.com/rjeczalik/notify)
-* [fsevents](https://github.com/fsnotify/fsevents)
+Related Projects
+----------------
+- [notify](https://github.com/rjeczalik/notify)
+- [fsevents](https://github.com/fsnotify/fsevents)