tag | 7669cb5d99760f2910c500dc956e919921571ee7 | |
---|---|---|
tagger | Martin Tournoij <martin@arp242.net> | Thu Oct 13 03:19:15 2022 +0200 |
object | 5f8c606accbcc6913853fe7e083ee461d181d88d |
Release v1.6.0 This version of fsnotify needs Go 1.16 (this was already the case since 1.5.1, but not documented). It also increases the minimum Linux version to 2.6.32. Additions - all: add `Event.Has()` and `Op.Has()` ([#477]) This makes checking events a lot easier; for example: if event.Op&Write == Write && !(event.Op&Remove == Remove) { } Becomes: if event.Has(Write) && !event.Has(Remove) { } - all: add cmd/fsnotify ([#463]) A command-line utility for testing and some examples. Changes and fixes - inotify: don't ignore events for files that don't exist ([#260], [#470]) Previously the inotify watcher would call `os.Lstat()` to check if a file still exists before emitting events. This was inconsistent with other platforms and resulted in inconsistent event reporting (e.g. when a file is quickly removed and re-created), and generally a source of confusion. It was added in 2013 to fix a memory leak that no longer exists. - all: return `ErrNonExistentWatch` when `Remove()` is called on a path that's not watched ([#460]) - inotify: replace epoll() with non-blocking inotify ([#434]) Non-blocking inotify was not generally available at the time this library was written in 2014, but now it is. As a result, the minimum Linux version is bumped from 2.6.27 to 2.6.32. This hugely simplifies the code and is faster. - kqueue: don't check for events every 100ms ([#480]) The watcher would wake up every 100ms, even when there was nothing to do. Now it waits until there is something to do. - macos: retry opening files on EINTR ([#475]) - kqueue: skip unreadable files ([#479]) kqueue requires a file descriptor for every file in a directory; this would fail if a file was unreadable by the current user. Now these files are simply skipped. - windows: fix renaming a watched directory if the parent is also watched ([#370]) - windows: increase buffer size from 4K to 64K ([#485]) - windows: close file handle on Remove() ([#288]) - kqueue: put pathname in the error if watching a file fails ([#471]) - inotify, windows: calling Close() more than once could race ([#465]) - kqueue: improve Close() performance ([#233]) - all: various documentation additions and clarifications. [#233]: https://github.com/fsnotify/fsnotify/pull/233 [#260]: https://github.com/fsnotify/fsnotify/pull/260 [#288]: https://github.com/fsnotify/fsnotify/pull/288 [#370]: https://github.com/fsnotify/fsnotify/pull/370 [#434]: https://github.com/fsnotify/fsnotify/pull/434 [#460]: https://github.com/fsnotify/fsnotify/pull/460 [#463]: https://github.com/fsnotify/fsnotify/pull/463 [#465]: https://github.com/fsnotify/fsnotify/pull/465 [#470]: https://github.com/fsnotify/fsnotify/pull/470 [#471]: https://github.com/fsnotify/fsnotify/pull/471 [#475]: https://github.com/fsnotify/fsnotify/pull/475 [#477]: https://github.com/fsnotify/fsnotify/pull/477 [#479]: https://github.com/fsnotify/fsnotify/pull/479 [#480]: https://github.com/fsnotify/fsnotify/pull/480 [#485]: https://github.com/fsnotify/fsnotify/pull/485
commit | 5f8c606accbcc6913853fe7e083ee461d181d88d | [log] [tgz] |
---|---|---|
author | Martin Tournoij <martin@arp242.net> | Thu Oct 13 03:18:11 2022 +0200 |
committer | Martin Tournoij <martin@arp242.net> | Thu Oct 13 03:18:11 2022 +0200 |
tree | 566d47ec45f239dd7674a3f0ad54d40fe76c482e | |
parent | 887858705e35407d7482aec89ebbbec5fc884d07 [diff] |
Update ChangeLog
fsnotify is a Go library to provide cross-platform filesystem notifications on Windows, Linux, macOS, and BSD systems.
Go 1.16 or newer is required; the full documentation is at https://pkg.go.dev/github.com/fsnotify/fsnotify
It‘s best to read the documentation at pkg.go.dev, as it’s pinned to the last released version, whereas this README is for the last development version which may include additions/changes.
Platform support:
Adapter | OS | Status |
---|---|---|
inotify | Linux 2.6.32+ | Supported |
kqueue | BSD, macOS | Supported |
ReadDirectoryChangesW | Windows | Supported |
FSEvents | macOS | Planned |
FEN | Solaris 11 | In Progress |
fanotify | Linux 5.9+ | Maybe |
USN Journals | Windows | Maybe |
Polling | All | Maybe |
Linux and macOS should include Android and iOS, but these are currently untested.
A basic example:
package main import ( "log" "github.com/fsnotify/fsnotify" ) func main() { // Create new watcher. watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() // Start listening for events. go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } log.Println("event:", event) if event.Has(fsnotify.Write) { log.Println("modified file:", event.Name) } case err, ok := <-watcher.Errors: if !ok { return } log.Println("error:", err) } } }() // Add a path. err = watcher.Add("/tmp") if err != nil { log.Fatal(err) } // Block main goroutine forever. <-make(chan struct{}) }
Some more examples can be found in cmd/fsnotify, which can be run with:
% go run ./cmd/fsnotify
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).
As of now, yes (you can read both channels in the same goroutine using select
, you don't need a separate goroutine for both channels; see the example).
fsnotify requires support from underlying OS to work. The current NFS and SMB protocols does not provide network level support for file notifications, and neither do the /proc and /sys virtual filesystems.
This could be fixed with a polling watcher (#9), but it's not yet implemented.
When a file is removed a REMOVE event won't be emitted until all file descriptors are closed; it will emit a CHMOD instead:
fp := os.Open("file") os.Remove("file") // CHMOD fp.Close() // REMOVE
This is the event that inotify sends, so not much can be changed about this.
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
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
To make the changes persist on reboot edit /etc/sysctl.conf
or /usr/lib/sysctl.d/50-default.conf
(details differ per Linux distro; check your distro's documentation):
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.
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.
The sysctl variables kern.maxfiles
and kern.maxfilesperproc
can be used to control the maximum number of open files.
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).