### Run the fsnotify example command Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Executes the example utility provided within the package repository. ```bash % go run ./cmd/fsnotify ``` -------------------------------- ### func (*Watcher) AddWith Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Starts monitoring a path with additional configuration options. ```APIDOC ## func (*Watcher) AddWith(path string, opts ...addOpt) ### Description Starts monitoring the path with specific options. Currently supports WithBufferSize for the Windows backend. ### Parameters #### Parameters - **path** (string) - Required - The file or directory path to monitor. - **opts** (...addOpt) - Optional - Configuration options such as WithBufferSize. ### Response - **error** (error) - Returns an error if the operation fails. ``` -------------------------------- ### FSNOTIFY_DEBUG Output Example Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Example of the output generated when the FSNOTIFY_DEBUG environment variable is set to 1. ```text FSNOTIFY_DEBUG: 11:34:23.633087586 256:IN_CREATE → "/tmp/file-1" FSNOTIFY_DEBUG: 11:34:23.633202319 4:IN_ATTRIB → "/tmp/file-1" FSNOTIFY_DEBUG: 11:34:28.989728764 512:IN_DELETE → "/tmp/file-1" ``` -------------------------------- ### Add Path with Options Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Starts monitoring a path with additional configuration options, such as buffer size for Windows. ```go func (w *Watcher) AddWith(path string, opts ...addOpt) error ``` -------------------------------- ### func (*Watcher) Add Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Starts monitoring a specific path for file system changes. ```APIDOC ## func (*Watcher) Add(path string) ### Description Starts monitoring the specified path for changes. A path can only be watched once; watching it more than once is a no-op. Paths that do not exist cannot be watched. ### Parameters #### Parameters - **path** (string) - Required - The file or directory path to monitor. ### Response - **error** (error) - Returns ErrClosed if the watcher is closed, or other errors related to filesystem access. ``` -------------------------------- ### Add Path to Watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Starts monitoring a specific file or directory path for changes. ```go func (w *Watcher) Add(path string) error ``` -------------------------------- ### Get list of watched paths in fsnotify Source: https://pkg.go.dev/github.com/fsnotify/fsnotify WatchList returns all paths explicitly added with Watcher.Add (and are not yet removed). The order is undefined, and may differ per call. Returns nil if Watcher.Close was called. ```go func (w *Watcher) WatchList() []string ``` -------------------------------- ### Initialize and use a filesystem watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Demonstrates creating a watcher, listening for events and errors in a goroutine, and adding a directory to watch. ```go 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{}) } ``` -------------------------------- ### Create Standard Watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Initializes a new standard Watcher instance. ```go func NewWatcher() (*Watcher, error) ``` -------------------------------- ### Create Buffered Watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Initializes a new Watcher with a custom buffer size for the events channel. ```go func NewBufferedWatcher(sz uint) (*Watcher, error) ``` -------------------------------- ### WithBufferSize Function Signature Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Function signature for configuring the buffer size on Windows. ```go func WithBufferSize(bytes int) addOpt ``` -------------------------------- ### Linux File Removal Event Behavior Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Demonstrates the sequence of events triggered on Linux when a file is removed while a file descriptor is open. ```go fp := os.Open("file") os.Remove("file") // Triggers Chmod fp.Close() // Triggers Remove ``` -------------------------------- ### Handle Linux File Removal Events Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Demonstrates the sequence of events on Linux where a file removal emits a CHMOD event until the file descriptor is closed. ```go fp := os.Open("file") os.Remove("file") // CHMOD fp.Close() // REMOVE ``` -------------------------------- ### kqueue (macOS, BSD) Specific Behavior Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Details the file descriptor usage and system limits for kqueue on macOS and BSD systems. ```APIDOC ## kqueue (macOS, all BSD systems) File Descriptor Limits ### Description On macOS and BSD systems using kqueue, each file being watched requires its own file descriptor. Watching a directory with five files, for instance, consumes six file descriptors (one for the directory, five for the files). This can lead to hitting the system's "max open files" limit more quickly compared to other systems. ### System Limits The `kern.maxfiles` and `kern.maxfilesperproc` sysctl variables control the maximum number of open files allowed system-wide and per process, respectively. Adjusting these values can help mitigate "too many open files" errors when using fsnotify with kqueue. #### Viewing Limits ```bash sysctl kern.maxfiles sysctl kern.maxfilesperproc ``` #### Modifying Limits (Temporary) ```bash sysctl kern.maxfiles=20000 sysctl kern.maxfilesperproc=10000 ``` #### Modifying Limits (Persistent) Similar to Linux, persistent changes can be made by editing `/etc/sysctl.conf` or files within `/etc/sysctl.d/`. ``` kern.maxfiles=20000 kern.maxfilesperproc=10000 ``` Consult your specific BSD or macOS distribution's documentation for the exact procedure. ``` -------------------------------- ### Package Variables Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Common errors returned by the fsnotify package. ```go var ( // ErrNonExistentWatch is used when Remove() is called on a path that's not // added. ErrNonExistentWatch = errors.New("fsnotify: can't remove non-existent watch") // ErrClosed is used when trying to operate on a closed Watcher. ErrClosed = errors.New("fsnotify: watcher already closed") // ErrEventOverflow is reported from the Errors channel when there are too // many events: // // - inotify: inotify returns IN_Q_OVERFLOW – because there are too // many queued events (the fs.inotify.max_queued_events // sysctl can be used to increase this). // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. // - kqueue, fen: Not used. ErrEventOverflow = errors.New("fsnotify: queue or buffer overflow") ) ``` -------------------------------- ### Configure Linux Inotify Limits Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Commands to adjust inotify watch limits via sysctl or configuration files. ```bash # Default values on Linux 5.18 sysctl fs.inotify.max_user_watches=124983 sysctl fs.inotify.max_user_instances=128 ``` ```bash fs.inotify.max_user_watches=124983 fs.inotify.max_user_instances=128 ``` -------------------------------- ### Configure Linux Inotify Limits Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Commands to adjust the maximum number of inotify watches and instances on Linux systems. ```bash # The default values on Linux 5.18 sysctl fs.inotify.max_user_watches=124983 sysctl fs.inotify.max_user_instances=128 ``` ```bash fs.inotify.max_user_watches=124983 fs.inotify.max_user_instances=128 ``` -------------------------------- ### Linux Specific Behavior Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Explains the behavior of fsnotify on Linux regarding file removal events and inotify system limits. ```APIDOC ## Linux File Removal Behavior ### Description When a file is removed on Linux, a `REMOVE` event is not emitted until all file descriptors are closed. Instead, a `CHMOD` event is emitted. The `REMOVE` event is then emitted when the file descriptor is closed. ### Example Scenario ```go fp := os.Open("file") os.Remove("file") // CHMOD event emitted fp.Close() // REMOVE event emitted ``` ### Inotify Limits The `fs.inotify.max_user_watches` sysctl variable limits the number of watches per user, and `fs.inotify.max_user_instances` limits the number of inotify instances per user. Each `Watcher` created is an instance, and each path added is a watch. These limits can be viewed and modified via `/proc` or `sysctl`. #### Viewing Limits ```bash cat /proc/sys/fs/inotify/max_user_watches cat /proc/sys/fs/inotify/max_user_instances ``` #### Modifying Limits (Temporary) ```bash sysctl fs.inotify.max_user_watches=124983 sysctl fs.inotify.max_user_instances=128 ``` #### Modifying Limits (Persistent) Edit `/etc/sysctl.conf` or a file in `/usr/lib/sysctl.d/` (e.g., `/usr/lib/sysctl.d/50-default.conf`) and add the following lines: ``` fs.inotify.max_user_watches=124983 fs.inotify.max_user_instances=128 ``` Reaching these limits can result in "no space left on device" or "too many open files" errors. ``` -------------------------------- ### fsnotify.Watcher API Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Documentation for the Watcher type and its associated methods for managing file system watches. ```APIDOC ## fsnotify.Watcher API ### Description The `Watcher` type provides the core functionality for monitoring file system events. It allows you to add and remove paths to watch, and retrieve events and errors. ### Constructor Functions #### `func NewWatcher() (*Watcher, error)` Creates a new `Watcher` instance with default settings. #### `func NewBufferedWatcher(sz uint) (*Watcher, error)` Creates a new `Watcher` instance with a specified buffer size for events. This is particularly relevant for Windows systems. ### Methods #### `func (w *Watcher) Add(path string) error` Adds a file or directory path to be watched. Returns an error if the path cannot be watched. #### `func (w *Watcher) AddWith(path string, opts ...addOpt) error` Adds a file or directory path to be watched with additional options. `opts` can include configurations like buffer size. #### `func (w *Watcher) Remove(path string) error` Removes a previously added path from being watched. Returns `ErrNonExistentWatch` if the path was not found. #### `func (w *Watcher) Close() error` Closes the watcher and releases any associated resources. Operations on a closed watcher will return `ErrClosed`. #### `func (w *Watcher) WatchList() []string` Returns a slice of strings representing all the paths currently being watched. ``` -------------------------------- ### fsnotify.WithBufferSize Function Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Details the WithBufferSize option for configuring the event buffer size, primarily for Windows. ```APIDOC ## func WithBufferSize(bytes int) addOpt ### Description `WithBufferSize` is an option function used with `AddWith` to set the buffer size for `ReadDirectoryChangesW` on Windows systems. It is a no-op on other operating systems. ### Parameters - **`bytes`** (int): The desired buffer size in bytes. The default is 64KB (65536 bytes), which is generally sufficient and compatible across filesystems. ### Usage Increase the buffer size if you encounter `ErrEventOverflow` errors, indicating that the default buffer is too small to handle bursts of file system events. ```go watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() // Increase buffer size to 1MB err = watcher.AddWith("/path/to/watch", fsnotify.WithBufferSize(1024*1024)) if err != nil { log.Fatal(err) } ``` ``` -------------------------------- ### FSNOTIFY_DEBUG Environment Variable Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Instructions on how to enable and interpret debug messages for fsnotify. ```APIDOC ## FSNOTIFY_DEBUG Environment Variable ### Description To enable debug messages for the fsnotify package, set the `FSNOTIFY_DEBUG` environment variable to `"1"`. These messages are printed to standard error (`stderr`) and can be invaluable for diagnosing issues, particularly when fsnotify is used as an indirect dependency. Debug output provides a low-level view of events as they are processed by fsnotify, with minimal transformation. ### Enabling Debugging Set the environment variable before running your application: ```bash export FSNOTIFY_DEBUG=1 ./your_application ``` ### Example Output The output format typically includes the timestamp, event flags, event name, and the affected path: ``` FSNOTIFY_DEBUG: 11:34:23.633087586 256:IN_CREATE → "/tmp/file-1" FSNOTIFY_DEBUG: 11:34:23.633202319 4:IN_ATTRIB → "/tmp/file-1" FSNOTIFY_DEBUG: 11:34:28.989728764 512:IN_DELETE → "/tmp/file-1" ``` ``` -------------------------------- ### func NewWatcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Creates a new Watcher instance to monitor file system events. ```APIDOC ## func NewWatcher() ### Description Creates a new Watcher instance. ### Response - **Watcher** (*Watcher) - A pointer to the newly created Watcher instance. - **error** (error) - Returns an error if the watcher could not be initialized. ``` -------------------------------- ### Event Type Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Represents a file system notification, including the path and the operation that triggered the event. ```APIDOC ## Event Type ### Description Event represents a file system notification. ### Fields - **Name** (string) - Path to the file or directory. Paths are relative to the input; for example with Add("dir") the Name will be set to "dir/file" if you create that file, but if you use Add("/path/to/dir") it will be "/path/to/dir/file". - **Op** (Op) - File operation that triggered the event. This is a bitmask and some systems may send multiple operations at once. Use the Event.Has() method instead of comparing with ==. ### Methods - **Has**(op Op) bool - Reports if this event has the given operation. - **String**() string - Returns a string representation of the event with their path. ``` -------------------------------- ### fsnotify.Op Type Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Explains the Op type, which represents file system operations and provides methods for checking operations. ```APIDOC ## fsnotify.Op Type ### Description The `Op` type is a bitmask that represents various file system operations that can trigger an event. It allows for checking multiple operations efficiently. ### Constants (Examples) - `fsnotify.Create`: A file or directory was created. - `fsnotify.Write`: A file was written to. - `fsnotify.Remove`: A file or directory was removed. - `fsnotify.Rename`: A file or directory was renamed. - `fsnotify.Chmod`: Metadata of a file or directory was changed. ### Methods #### `func (o Op) Has(h Op) bool` Checks if the operation mask `o` contains the specified operation `h`. This is useful for determining if a specific type of operation occurred. Example: ```go if event.Op.Has(fsnotify.Write | fsnotify.Create) { fmt.Println("File was written to or created.") } ``` #### `func (o Op) String() string` Returns a string representation of the `Op` mask, listing the operations included in the mask. ``` -------------------------------- ### Watcher.WatchList() Source: https://pkg.go.dev/github.com/fsnotify/fsnotify WatchList returns a slice of all paths that have been explicitly added using Watcher.Add and have not yet been removed. The order of paths in the returned slice is undefined. ```APIDOC ## WatchList ### Description Retrieves a list of all currently monitored paths. ### Method `WatchList() []string` ### Parameters None ### Returns - `[]string`: A slice containing all paths currently being watched. Returns `nil` if Watcher.Close was called. ``` -------------------------------- ### Watcher Type Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Watches a set of paths, delivering events on a channel. ```APIDOC ## Watcher Type ### Description Watcher watches a set of paths, delivering events on a channel. A watcher should not be copied (e.g. pass it by pointer, rather than by value). ### Fields - **Events** (chan Event) - Sends the filesystem change events. fsnotify can send the following events; a "path" here can refer to a file, directory, symbolic link, or special file like a FIFO. - fsnotify.Create: A new path was created; this may be followed by one or more Write events if data also gets written to a file. - fsnotify.Remove: A path was removed. - fsnotify.Rename: A path was renamed. A rename is always sent with the old path as Event.Name, and a Create event will be sent with the new name. Renames are only sent for paths that are currently watched; e.g. moving an unmonitored file into a monitored directory will show up as just a Create. Similarly, renaming a file to outside a monitored directory will show up as only a Rename. - fsnotify.Write: A file or named pipe was written to. A Truncate will also trigger a Write. A single "write action" initiated by the user may show up as one or multiple writes, depending on when the system syncs things to disk. Some systems may send Write event for directories when the directory content changes. - fsnotify.Chmod: Attributes were changed. On Linux this is also sent when a file is removed (or more accurately, when a link to an inode is removed). On kqueue it's sent when a file is truncated. On Windows it's never sent. - **Errors** (chan error) - Sends any errors. ``` -------------------------------- ### fsnotify.Event Type Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Details the Event type, its properties, and methods for checking event operations. ```APIDOC ## fsnotify.Event Type ### Description The `Event` type represents a file system event that has occurred. It contains information about the event's operation and the affected path. ### Fields - **`Path`** (string): The path to the file or directory where the event occurred. - **`Name`** (string): The name of the file or directory within the watched directory (if applicable). - **`Op`** (Op): A bitmask representing the operations that triggered the event. ### Methods #### `func (e Event) Has(op Op) bool` Checks if the event `e` contains the specified operation `op`. This is useful for filtering events based on specific operations. Example: ```go if event.Has(fsnotify.Create) { fmt.Printf("File created: %s\n", event.Path) } ``` #### `func (e Event) String() string` Returns a string representation of the `Event`, typically including the path and the operations performed. ``` -------------------------------- ### fsnotify Error Variables Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Lists and describes the common error variables returned by the fsnotify package. ```APIDOC ## fsnotify Error Variables ### Description The fsnotify package defines several error variables to indicate specific failure conditions. ### Error Definitions - **`ErrNonExistentWatch`** * Description: Returned when `Remove()` is called on a path that has not been added to the watcher. - **`ErrClosed`** * Description: Returned when an operation is attempted on a `Watcher` that has already been closed. - **`ErrEventOverflow`** * Description: Reported on the `Errors` channel when there are too many events to be processed. This can occur due to: * **inotify (Linux):** The inotify queue is full. The `fs.inotify.max_queued_events` sysctl can be adjusted to increase this limit. * **Windows:** The buffer size provided to `ReadDirectoryChangesW` is too small. Use `WithBufferSize()` to increase it. * **kqueue, fen:** This error is not typically used on these backends. ``` -------------------------------- ### Watcher.Remove(path string) Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Remove stops monitoring the specified path for changes. Directories are always removed non-recursively. Removing a path that has not yet been added returns ErrNonExistentWatch. ```APIDOC ## Remove ### Description Stops monitoring a specific path for file system changes. ### Method `Remove(path string)` ### Parameters #### Path Parameters - **path** (string) - Required - The path to stop monitoring. ### Returns - `error`: Returns `ErrNonExistentWatch` if the path was not being monitored. Returns `nil` if Watcher.Close was called. ``` -------------------------------- ### Remove path from fsnotify watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Remove stops monitoring the path for changes. Directories are always removed non-recursively. Removing a path that has not yet been added returns ErrNonExistentWatch. Returns nil if Watcher.Close was called. ```go func (w *Watcher) Remove(path string) error ``` -------------------------------- ### Op Type Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Describes a set of file operations that fsnotify can trigger. ```APIDOC ## Op Type ### Description Op describes a set of file operations. ### Constants - **Create** (Op) - A new pathname was created. - **Write** (Op) - The pathname was written to; this does *not* mean the write has finished, and a write can be followed by more writes. - **Remove** (Op) - The path was removed; any watches on it will be removed. Some "remove" operations may trigger a Rename if the file is actually moved (for example "remove to trash" is often a rename). - **Rename** (Op) - The path was renamed to something else; any watches on it will be removed. - **Chmod** (Op) - File attributes were changed. It's generally not recommended to take action on this event, as it may get triggered very frequently by some software. For example, Spotlight indexing on macOS, anti-virus software, backup software, etc. ### Methods - **Has**(h Op) bool - Reports if this operation has the given operation. - **String**() string - Returns a string representation of the operation. ``` -------------------------------- ### Watcher.Close() Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Close removes all watches and closes the Events channel. It returns an error if the watcher has already been closed. ```APIDOC ## Close ### Description Closes the watcher, removing all watches and the Events channel. ### Method `Close` ### Parameters None ### Returns - `error`: Returns nil if Watcher.Close was called. Returns an error if the watcher is already closed. ``` -------------------------------- ### func NewBufferedWatcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Creates a new Watcher with a buffered Events channel, useful for high-event scenarios. ```APIDOC ## func NewBufferedWatcher(sz uint) ### Description Creates a new Watcher with a buffered Watcher.Events channel. This is intended for situations with a very large number of events where kernel buffer sizes cannot be increased. ### Parameters #### Parameters - **sz** (uint) - Required - The size of the buffer for the Events channel. ### Response - **Watcher** (*Watcher) - A pointer to the newly created Watcher instance. - **error** (error) - Returns an error if the watcher could not be initialized. ``` -------------------------------- ### Close fsnotify watcher Source: https://pkg.go.dev/github.com/fsnotify/fsnotify Close removes all watches and closes the Events channel. Returns nil if Watcher.Close was called. ```go func (w *Watcher) Close() error ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.