@@ -8,12 +8,102 @@ import (
88)
99
1010// Watcher watches a set of files, delivering events to a channel.
11+ //
12+ // A watcher should not be copied (e.g. pass it by pointer, rather than by
13+ // value).
14+ //
15+ // # Linux notes
16+ //
17+ // When a file is removed a Remove event won't be emitted until all file
18+ // descriptors are closed, and deletes will always emit a Chmod. For example:
19+ //
20+ // fp := os.Open("file")
21+ // os.Remove("file") // Triggers Chmod
22+ // fp.Close() // Triggers Remove
23+ //
24+ // The fs.inotify.max_user_watches sysctl variable specifies the upper limit
25+ // for the number of watches per user, and fs.inotify.max_user_instances
26+ // specifies the maximum number of inotify instances per user. Every Watcher you
27+ // create is an "instance", and every path you add is a "watch".
28+ //
29+ // These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and
30+ // /proc/sys/fs/inotify/max_user_instances
31+ //
32+ // To increase them you can use sysctl or write the value to the /proc file:
33+ //
34+ // # Default values on Linux 5.18
35+ // sysctl fs.inotify.max_user_watches=124983
36+ // sysctl fs.inotify.max_user_instances=128
37+ //
38+ // To make the changes persist on reboot edit /etc/sysctl.conf or
39+ // /usr/lib/sysctl.d/50-default.conf (on some systemd systems):
40+ //
41+ // fs.inotify.max_user_watches=124983
42+ // fs.inotify.max_user_instances=128
43+ //
44+ // Reaching the limit will result in a "no space left on device" or "too many open
45+ // files" error.
46+ //
47+ // # kqueue notes (macOS, BSD)
48+ //
49+ // kqueue requires opening a file descriptor for every file that's being watched;
50+ // so if you're watching a directory with five files then that's six file
51+ // descriptors. You will run in to your system's "max open files" limit faster on
52+ // these platforms.
53+ //
54+ // The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to
55+ // control the maximum number of open files, as well as /etc/login.conf on BSD
56+ // systems.
57+ //
58+ // # macOS notes
59+ //
60+ // Spotlight indexing on macOS can result in multiple events (see [#15]). A
61+ // temporary workaround is to add your folder(s) to the "Spotlight Privacy
62+ // Settings" until we have a native FSEvents implementation (see [#11]).
63+ //
64+ // [#11]: https://github.com/fsnotify/fsnotify/issues/11
65+ // [#15]: https://github.com/fsnotify/fsnotify/issues/15
1166type Watcher struct {
67+ // Events sends the filesystem change events.
68+ //
69+ // fsnotify can send the following events; a "path" here can refer to a
70+ // file, directory, symbolic link, or special files like a FIFO.
71+ //
72+ // fsnotify.Create A new path was created; this may be followed by one
73+ // or more Write events if data also gets written to a
74+ // file.
75+ //
76+ // fsnotify.Remove A path was removed.
77+ //
78+ // fsnotify.Rename A path was renamed. A rename is always sent with the
79+ // old path as [Event.Name], and a Create event will be
80+ // sent with the new name. Renames are only sent for
81+ // paths that are currently watched; e.g. moving an
82+ // unmonitored file into a monitored directory will
83+ // show up as just a Create. Similarly, renaming a file
84+ // to outside a monitored directory will show up as
85+ // only a Rename.
86+ //
87+ // fsnotify.Write A file or named pipe was written to. A Truncate will
88+ // also trigger a Write. A single "write action"
89+ // initiated by the user may show up as one or multiple
90+ // writes, depending on when the system syncs things to
91+ // disk. For example when compiling a large Go program
92+ // you may get hundreds of Write events, so you
93+ // probably want to wait until you've stopped receiving
94+ // them (see the dedup example in cmd/fsnotify).
95+ //
96+ // fsnotify.Chmod Attributes were changes (never sent on Windows). On
97+ // Linux this is also sent when a file is removed (or
98+ // more accurately, when a link to an inode is
99+ // removed), and on kqueue when a file is truncated.
12100 Events chan Event
101+
102+ // Errors sends any errors.
13103 Errors chan error
14104}
15105
16- // NewWatcher establishes a new watcher with the underlying OS and begins waiting for events .
106+ // NewWatcher creates a new Watcher .
17107func NewWatcher () (* Watcher , error ) {
18108 return nil , errors .New ("FEN based watcher not yet supported for fsnotify\n " )
19109}
@@ -23,12 +113,46 @@ func (w *Watcher) Close() error {
23113 return nil
24114}
25115
26- // Add starts watching the named file or directory (non-recursively).
116+ // Add starts monitoring the path for changes.
117+ //
118+ // A path can only be watched once; attempting to watch it more than once will
119+ // return an error. Paths that do not yet exist on the filesystem cannot be
120+ // added. A watch will be automatically removed if the path is deleted.
121+ //
122+ // A path will remain watched if it gets renamed to somewhere else on the same
123+ // filesystem, but the monitor will get removed if the path gets deleted and
124+ // re-created.
125+ //
126+ // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
127+ // filesystems (/proc, /sys, etc.) generally don't work.
128+ //
129+ // # Watching directories
130+ //
131+ // All files in a directory are monitored, including new files that are created
132+ // after the watcher is started. Subdirectories are not watched (i.e. it's
133+ // non-recursive).
134+ //
135+ // # Watching files
136+ //
137+ // Watching individual files (rather than directories) is generally not
138+ // recommended as many tools update files atomically. Instead of "just" writing
139+ // to the file a temporary file will be written to first, and if successful the
140+ // temporary file is moved to to destination, removing the original, or some
141+ // variant thereof. The watcher on the original file is now lost, as it no
142+ // longer exists.
143+ //
144+ // Instead, watch the parent directory and use [Event.Name] to filter out files
145+ // you're not interested in. There is an example of this in cmd/fsnotify/file.go
27146func (w * Watcher ) Add (name string ) error {
28147 return nil
29148}
30149
31- // Remove stops watching the the named file or directory (non-recursively).
150+ // Remove stops monitoring the path for changes.
151+ //
152+ // Directories are always removed non-recursively. For example, if you added
153+ // /tmp/dir and /tmp/dir/subdir then you will need to remove both.
154+ //
155+ // Removing a path that has not yet been added returns [ErrNonExistentWatch].
32156func (w * Watcher ) Remove (name string ) error {
33157 return nil
34158}
0 commit comments