aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/fsnotify
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/fsnotify
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/fsnotify')
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.cirrus.yml13
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.editorconfig12
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.gitattributes1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.gitignore7
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.mailmap2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/CHANGELOG.md541
-rw-r--r--vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md26
-rw-r--r--vendor/github.com/fsnotify/fsnotify/LICENSE25
-rw-r--r--vendor/github.com/fsnotify/fsnotify/README.md184
-rw-r--r--vendor/github.com/fsnotify/fsnotify/backend_fen.go640
-rw-r--r--vendor/github.com/fsnotify/fsnotify/backend_inotify.go594
-rw-r--r--vendor/github.com/fsnotify/fsnotify/backend_kqueue.go782
-rw-r--r--vendor/github.com/fsnotify/fsnotify/backend_other.go205
-rw-r--r--vendor/github.com/fsnotify/fsnotify/backend_windows.go827
-rw-r--r--vendor/github.com/fsnotify/fsnotify/fsnotify.go146
-rw-r--r--vendor/github.com/fsnotify/fsnotify/mkdoc.zsh259
-rw-r--r--vendor/github.com/fsnotify/fsnotify/system_bsd.go8
-rw-r--r--vendor/github.com/fsnotify/fsnotify/system_darwin.go9
18 files changed, 0 insertions, 4281 deletions
diff --git a/vendor/github.com/fsnotify/fsnotify/.cirrus.yml b/vendor/github.com/fsnotify/fsnotify/.cirrus.yml
deleted file mode 100644
index ffc7b992b..000000000
--- a/vendor/github.com/fsnotify/fsnotify/.cirrus.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-freebsd_task:
- name: 'FreeBSD'
- freebsd_instance:
- image_family: freebsd-13-2
- install_script:
- - pkg update -f
- - pkg install -y go
- test_script:
- # run tests as user "cirrus" instead of root
- - pw useradd cirrus -m
- - chown -R cirrus:cirrus .
- - FSNOTIFY_BUFFER=4096 sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
- - sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./...
diff --git a/vendor/github.com/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig
deleted file mode 100644
index fad895851..000000000
--- a/vendor/github.com/fsnotify/fsnotify/.editorconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-root = true
-
-[*.go]
-indent_style = tab
-indent_size = 4
-insert_final_newline = true
-
-[*.{yml,yaml}]
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes
deleted file mode 100644
index 32f1001be..000000000
--- a/vendor/github.com/fsnotify/fsnotify/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-go.sum linguist-generated
diff --git a/vendor/github.com/fsnotify/fsnotify/.gitignore b/vendor/github.com/fsnotify/fsnotify/.gitignore
deleted file mode 100644
index 391cc076b..000000000
--- a/vendor/github.com/fsnotify/fsnotify/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# go test -c output
-*.test
-*.test.exe
-
-# Output of go build ./cmd/fsnotify
-/fsnotify
-/fsnotify.exe
diff --git a/vendor/github.com/fsnotify/fsnotify/.mailmap b/vendor/github.com/fsnotify/fsnotify/.mailmap
deleted file mode 100644
index a04f2907f..000000000
--- a/vendor/github.com/fsnotify/fsnotify/.mailmap
+++ /dev/null
@@ -1,2 +0,0 @@
-Chris Howey <howeyc@gmail.com> <chris@howey.me>
-Nathan Youngman <git@nathany.com> <4566+nathany@users.noreply.github.com>
diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
deleted file mode 100644
index e0e575754..000000000
--- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
+++ /dev/null
@@ -1,541 +0,0 @@
-# Changelog
-
-Unreleased
-----------
-Nothing yet.
-
-1.7.0 - 2023-10-22
-------------------
-This version of fsnotify needs Go 1.17.
-
-### Additions
-
-- illumos: add FEN backend to support illumos and Solaris. ([#371])
-
-- all: add `NewBufferedWatcher()` to use a buffered channel, which can be useful
- in cases where you can't control the kernel buffer and receive a large number
- of events in bursts. ([#550], [#572])
-
-- all: add `AddWith()`, which is identical to `Add()` but allows passing
- options. ([#521])
-
-- windows: allow setting the ReadDirectoryChangesW() buffer size with
- `fsnotify.WithBufferSize()`; the default of 64K is the highest value that
- works on all platforms and is enough for most purposes, but in some cases a
- highest buffer is needed. ([#521])
-
-### Changes and fixes
-
-- inotify: remove watcher if a watched path is renamed ([#518])
-
- After a rename the reported name wasn't updated, or even an empty string.
- Inotify doesn't provide any good facilities to update it, so just remove the
- watcher. This is already how it worked on kqueue and FEN.
-
- On Windows this does work, and remains working.
-
-- windows: don't listen for file attribute changes ([#520])
-
- File attribute changes are sent as `FILE_ACTION_MODIFIED` by the Windows API,
- with no way to see if they're a file write or attribute change, so would show
- up as a fsnotify.Write event. This is never useful, and could result in many
- spurious Write events.
-
-- windows: return `ErrEventOverflow` if the buffer is full ([#525])
-
- Before it would merely return "short read", making it hard to detect this
- error.
-
-- kqueue: make sure events for all files are delivered properly when removing a
- watched directory ([#526])
-
- Previously they would get sent with `""` (empty string) or `"."` as the path
- name.
-
-- kqueue: don't emit spurious Create events for symbolic links ([#524])
-
- The link would get resolved but kqueue would "forget" it already saw the link
- itself, resulting on a Create for every Write event for the directory.
-
-- all: return `ErrClosed` on `Add()` when the watcher is closed ([#516])
-
-- other: add `Watcher.Errors` and `Watcher.Events` to the no-op `Watcher` in
- `backend_other.go`, making it easier to use on unsupported platforms such as
- WASM, AIX, etc. ([#528])
-
-- other: use the `backend_other.go` no-op if the `appengine` build tag is set;
- Google AppEngine forbids usage of the unsafe package so the inotify backend
- won't compile there.
-
-[#371]: https://github.com/fsnotify/fsnotify/pull/371
-[#516]: https://github.com/fsnotify/fsnotify/pull/516
-[#518]: https://github.com/fsnotify/fsnotify/pull/518
-[#520]: https://github.com/fsnotify/fsnotify/pull/520
-[#521]: https://github.com/fsnotify/fsnotify/pull/521
-[#524]: https://github.com/fsnotify/fsnotify/pull/524
-[#525]: https://github.com/fsnotify/fsnotify/pull/525
-[#526]: https://github.com/fsnotify/fsnotify/pull/526
-[#528]: https://github.com/fsnotify/fsnotify/pull/528
-[#537]: https://github.com/fsnotify/fsnotify/pull/537
-[#550]: https://github.com/fsnotify/fsnotify/pull/550
-[#572]: https://github.com/fsnotify/fsnotify/pull/572
-
-1.6.0 - 2022-10-13
-------------------
-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
-
-## [1.5.4] - 2022-04-25
-
-* Windows: add missing defer to `Watcher.WatchList` [#447](https://github.com/fsnotify/fsnotify/pull/447)
-* go.mod: use latest x/sys [#444](https://github.com/fsnotify/fsnotify/pull/444)
-* Fix compilation for OpenBSD [#443](https://github.com/fsnotify/fsnotify/pull/443)
-
-## [1.5.3] - 2022-04-22
-
-* This version is retracted. An incorrect branch is published accidentally [#445](https://github.com/fsnotify/fsnotify/issues/445)
-
-## [1.5.2] - 2022-04-21
-
-* Add a feature to return the directories and files that are being monitored [#374](https://github.com/fsnotify/fsnotify/pull/374)
-* Fix potential crash on windows if `raw.FileNameLength` exceeds `syscall.MAX_PATH` [#361](https://github.com/fsnotify/fsnotify/pull/361)
-* Allow build on unsupported GOOS [#424](https://github.com/fsnotify/fsnotify/pull/424)
-* Don't set `poller.fd` twice in `newFdPoller` [#406](https://github.com/fsnotify/fsnotify/pull/406)
-* fix go vet warnings: call to `(*T).Fatalf` from a non-test goroutine [#416](https://github.com/fsnotify/fsnotify/pull/416)
-
-## [1.5.1] - 2021-08-24
-
-* Revert Add AddRaw to not follow symlinks [#394](https://github.com/fsnotify/fsnotify/pull/394)
-
-## [1.5.0] - 2021-08-20
-
-* Go: Increase minimum required version to Go 1.12 [#381](https://github.com/fsnotify/fsnotify/pull/381)
-* Feature: Add AddRaw method which does not follow symlinks when adding a watch [#289](https://github.com/fsnotify/fsnotify/pull/298)
-* Windows: Follow symlinks by default like on all other systems [#289](https://github.com/fsnotify/fsnotify/pull/289)
-* CI: Use GitHub Actions for CI and cover go 1.12-1.17
- [#378](https://github.com/fsnotify/fsnotify/pull/378)
- [#381](https://github.com/fsnotify/fsnotify/pull/381)
- [#385](https://github.com/fsnotify/fsnotify/pull/385)
-* Go 1.14+: Fix unsafe pointer conversion [#325](https://github.com/fsnotify/fsnotify/pull/325)
-
-## [1.4.9] - 2020-03-11
-
-* Move example usage to the readme #329. This may resolve #328.
-
-## [1.4.8] - 2020-03-10
-
-* CI: test more go versions (@nathany 1d13583d846ea9d66dcabbfefbfb9d8e6fb05216)
-* Tests: Queued inotify events could have been read by the test before max_queued_events was hit (@matthias-stone #265)
-* Tests: t.Fatalf -> t.Errorf in go routines (@gdey #266)
-* CI: Less verbosity (@nathany #267)
-* Tests: Darwin: Exchangedata is deprecated on 10.13 (@nathany #267)
-* Tests: Check if channels are closed in the example (@alexeykazakov #244)
-* CI: Only run golint on latest version of go and fix issues (@cpuguy83 #284)
-* CI: Add windows to travis matrix (@cpuguy83 #284)
-* Docs: Remover appveyor badge (@nathany 11844c0959f6fff69ba325d097fce35bd85a8e93)
-* Linux: create epoll and pipe fds with close-on-exec (@JohannesEbke #219)
-* Linux: open files with close-on-exec (@linxiulei #273)
-* Docs: Plan to support fanotify (@nathany ab058b44498e8b7566a799372a39d150d9ea0119 )
-* Project: Add go.mod (@nathany #309)
-* Project: Revise editor config (@nathany #309)
-* Project: Update copyright for 2019 (@nathany #309)
-* CI: Drop go1.8 from CI matrix (@nathany #309)
-* Docs: Updating the FAQ section for supportability with NFS & FUSE filesystems (@Pratik32 4bf2d1fec78374803a39307bfb8d340688f4f28e )
-
-## [1.4.7] - 2018-01-09
-
-* BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine)
-* Tests: Fix missing verb on format string (thanks @rchiossi)
-* Linux: Fix deadlock in Remove (thanks @aarondl)
-* Linux: Watch.Add improvements (avoid race, fix consistency, reduce garbage) (thanks @twpayne)
-* Docs: Moved FAQ into the README (thanks @vahe)
-* Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich)
-* Docs: replace references to OS X with macOS
-
-## [1.4.2] - 2016-10-10
-
-* Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack)
-
-## [1.4.1] - 2016-10-04
-
-* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack)
-
-## [1.4.0] - 2016-10-01
-
-* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie)
-
-## [1.3.1] - 2016-06-28
-
-* Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc)
-
-## [1.3.0] - 2016-04-19
-
-* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135)
-
-## [1.2.10] - 2016-03-02
-
-* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj)
-
-## [1.2.9] - 2016-01-13
-
-kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep)
-
-## [1.2.8] - 2015-12-17
-
-* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test)
-* inotify: fix race in test
-* enable race detection for continuous integration (Linux, Mac, Windows)
-
-## [1.2.5] - 2015-10-17
-
-* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki)
-* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken)
-* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie)
-* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion)
-
-## [1.2.1] - 2015-10-14
-
-* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx)
-
-## [1.2.0] - 2015-02-08
-
-* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD)
-* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD)
-* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59)
-
-## [1.1.1] - 2015-02-05
-
-* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD)
-
-## [1.1.0] - 2014-12-12
-
-* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43)
- * add low-level functions
- * only need to store flags on directories
- * less mutexes [#13](https://github.com/fsnotify/fsnotify/issues/13)
- * done can be an unbuffered channel
- * remove calls to os.NewSyscallError
-* More efficient string concatenation for Event.String() [#52](https://github.com/fsnotify/fsnotify/pull/52) (thanks @mdlayher)
-* kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48)
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
-
-## [1.0.4] - 2014-09-07
-
-* kqueue: add dragonfly to the build tags.
-* Rename source code files, rearrange code so exported APIs are at the top.
-* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang)
-
-## [1.0.3] - 2014-08-19
-
-* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36)
-
-## [1.0.2] - 2014-08-17
-
-* [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
-* [Fix] Make ./path and path equivalent. (thanks @zhsso)
-
-## [1.0.0] - 2014-08-15
-
-* [API] Remove AddWatch on Windows, use Add.
-* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30)
-* Minor updates based on feedback from golint.
-
-## dev / 2014-07-09
-
-* Moved to [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify).
-* Use os.NewSyscallError instead of returning errno (thanks @hariharan-uno)
-
-## dev / 2014-07-04
-
-* kqueue: fix incorrect mutex used in Close()
-* Update example to demonstrate usage of Op.
-
-## dev / 2014-06-28
-
-* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/fsnotify/fsnotify/issues/4)
-* Fix for String() method on Event (thanks Alex Brainman)
-* Don't build on Plan 9 or Solaris (thanks @4ad)
-
-## dev / 2014-06-21
-
-* Events channel of type Event rather than *Event.
-* [internal] use syscall constants directly for inotify and kqueue.
-* [internal] kqueue: rename events to kevents and fileEvent to event.
-
-## dev / 2014-06-19
-
-* Go 1.3+ required on Windows (uses syscall.ERROR_MORE_DATA internally).
-* [internal] remove cookie from Event struct (unused).
-* [internal] Event struct has the same definition across every OS.
-* [internal] remove internal watch and removeWatch methods.
-
-## dev / 2014-06-12
-
-* [API] Renamed Watch() to Add() and RemoveWatch() to Remove().
-* [API] Pluralized channel names: Events and Errors.
-* [API] Renamed FileEvent struct to Event.
-* [API] Op constants replace methods like IsCreate().
-
-## dev / 2014-06-12
-
-* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
-
-## dev / 2014-05-23
-
-* [API] Remove current implementation of WatchFlags.
- * current implementation doesn't take advantage of OS for efficiency
- * provides little benefit over filtering events as they are received, but has extra bookkeeping and mutexes
- * no tests for the current implementation
- * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195)
-
-## [0.9.3] - 2014-12-31
-
-* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
-
-## [0.9.2] - 2014-08-17
-
-* [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
-
-## [0.9.1] - 2014-06-12
-
-* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
-
-## [0.9.0] - 2014-01-17
-
-* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany)
-* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare)
-* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library.
-
-## [0.8.12] - 2013-11-13
-
-* [API] Remove FD_SET and friends from Linux adapter
-
-## [0.8.11] - 2013-11-02
-
-* [Doc] Add Changelog [#72][] (thanks @nathany)
-* [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond)
-
-## [0.8.10] - 2013-10-19
-
-* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott)
-* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer)
-* [Doc] specify OS-specific limits in README (thanks @debrando)
-
-## [0.8.9] - 2013-09-08
-
-* [Doc] Contributing (thanks @nathany)
-* [Doc] update package path in example code [#63][] (thanks @paulhammond)
-* [Doc] GoCI badge in README (Linux only) [#60][]
-* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany)
-
-## [0.8.8] - 2013-06-17
-
-* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie)
-
-## [0.8.7] - 2013-06-03
-
-* [API] Make syscall flags internal
-* [Fix] inotify: ignore event changes
-* [Fix] race in symlink test [#45][] (reported by @srid)
-* [Fix] tests on Windows
-* lower case error messages
-
-## [0.8.6] - 2013-05-23
-
-* kqueue: Use EVT_ONLY flag on Darwin
-* [Doc] Update README with full example
-
-## [0.8.5] - 2013-05-09
-
-* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg)
-
-## [0.8.4] - 2013-04-07
-
-* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz)
-
-## [0.8.3] - 2013-03-13
-
-* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin)
-* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin)
-
-## [0.8.2] - 2013-02-07
-
-* [Doc] add Authors
-* [Fix] fix data races for map access [#29][] (thanks @fsouza)
-
-## [0.8.1] - 2013-01-09
-
-* [Fix] Windows path separators
-* [Doc] BSD License
-
-## [0.8.0] - 2012-11-09
-
-* kqueue: directory watching improvements (thanks @vmirage)
-* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto)
-* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr)
-
-## [0.7.4] - 2012-10-09
-
-* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji)
-* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig)
-* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig)
-* [Fix] kqueue: modify after recreation of file
-
-## [0.7.3] - 2012-09-27
-
-* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage)
-* [Fix] kqueue: no longer get duplicate CREATE events
-
-## [0.7.2] - 2012-09-01
-
-* kqueue: events for created directories
-
-## [0.7.1] - 2012-07-14
-
-* [Fix] for renaming files
-
-## [0.7.0] - 2012-07-02
-
-* [Feature] FSNotify flags
-* [Fix] inotify: Added file name back to event path
-
-## [0.6.0] - 2012-06-06
-
-* kqueue: watch files after directory created (thanks @tmc)
-
-## [0.5.1] - 2012-05-22
-
-* [Fix] inotify: remove all watches before Close()
-
-## [0.5.0] - 2012-05-03
-
-* [API] kqueue: return errors during watch instead of sending over channel
-* kqueue: match symlink behavior on Linux
-* inotify: add `DELETE_SELF` (requested by @taralx)
-* [Fix] kqueue: handle EINTR (reported by @robfig)
-* [Doc] Godoc example [#1][] (thanks @davecheney)
-
-## [0.4.0] - 2012-03-30
-
-* Go 1 released: build with go tool
-* [Feature] Windows support using winfsnotify
-* Windows does not have attribute change notifications
-* Roll attribute notifications into IsModify
-
-## [0.3.0] - 2012-02-19
-
-* kqueue: add files when watch directory
-
-## [0.2.0] - 2011-12-30
-
-* update to latest Go weekly code
-
-## [0.1.0] - 2011-10-19
-
-* kqueue: add watch on file creation to match inotify
-* kqueue: create file event
-* inotify: ignore `IN_IGNORED` events
-* event String()
-* linux: common FileEvent functions
-* initial commit
-
-[#79]: https://github.com/howeyc/fsnotify/pull/79
-[#77]: https://github.com/howeyc/fsnotify/pull/77
-[#72]: https://github.com/howeyc/fsnotify/issues/72
-[#71]: https://github.com/howeyc/fsnotify/issues/71
-[#70]: https://github.com/howeyc/fsnotify/issues/70
-[#63]: https://github.com/howeyc/fsnotify/issues/63
-[#62]: https://github.com/howeyc/fsnotify/issues/62
-[#60]: https://github.com/howeyc/fsnotify/issues/60
-[#59]: https://github.com/howeyc/fsnotify/issues/59
-[#49]: https://github.com/howeyc/fsnotify/issues/49
-[#45]: https://github.com/howeyc/fsnotify/issues/45
-[#40]: https://github.com/howeyc/fsnotify/issues/40
-[#36]: https://github.com/howeyc/fsnotify/issues/36
-[#33]: https://github.com/howeyc/fsnotify/issues/33
-[#29]: https://github.com/howeyc/fsnotify/issues/29
-[#25]: https://github.com/howeyc/fsnotify/issues/25
-[#24]: https://github.com/howeyc/fsnotify/issues/24
-[#21]: https://github.com/howeyc/fsnotify/issues/21
diff --git a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md
deleted file mode 100644
index ea379759d..000000000
--- a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Thank you for your interest in contributing to fsnotify! We try to review and
-merge PRs in a reasonable timeframe, but please be aware that:
-
-- To avoid "wasted" work, please discus changes on the issue tracker first. You
- can just send PRs, but they may end up being rejected for one reason or the
- other.
-
-- fsnotify is a cross-platform library, and changes must work reasonably well on
- all supported platforms.
-
-- Changes will need to be compatible; old code should still compile, and the
- runtime behaviour can't change in ways that are likely to lead to problems for
- users.
-
-Testing
--------
-Just `go test ./...` runs all the tests; the CI runs this on all supported
-platforms. Testing different platforms locally can be done with something like
-[goon] or [Vagrant], but this isn't super-easy to set up at the moment.
-
-Use the `-short` flag to make the "stress test" run faster.
-
-
-[goon]: https://github.com/arp242/goon
-[Vagrant]: https://www.vagrantup.com/
-[integration_test.go]: /integration_test.go
diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE
deleted file mode 100644
index fb03ade75..000000000
--- a/vendor/github.com/fsnotify/fsnotify/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright © 2012 The Go Authors. All rights reserved.
-Copyright © fsnotify Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or
- other materials provided with the distribution.
-* Neither the name of Google Inc. nor the names of its contributors may be used
- to endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md
deleted file mode 100644
index e480733d1..000000000
--- a/vendor/github.com/fsnotify/fsnotify/README.md
+++ /dev/null
@@ -1,184 +0,0 @@
-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
-
----
-
-Platform support:
-
-| Backend | OS | Status |
-| :-------------------- | :--------- | :------------------------------------------------------------------------ |
-| inotify | Linux | Supported |
-| kqueue | BSD, macOS | Supported |
-| ReadDirectoryChangesW | Windows | Supported |
-| FEN | illumos | Supported |
-| fanotify | Linux 5.9+ | [Not yet](https://github.com/fsnotify/fsnotify/issues/114) |
-| AHAFS | AIX | [aix branch]; experimental due to lack of maintainer and test environment |
-| FSEvents | macOS | [Needs support in x/sys/unix][fsevents] |
-| USN Journals | Windows | [Needs support in x/sys/windows][usn] |
-| Polling | *All* | [Not yet](https://github.com/fsnotify/fsnotify/issues/9) |
-
-Linux and illumos should include Android and Solaris, but these are currently
-untested.
-
-[fsevents]: https://github.com/fsnotify/fsnotify/issues/11#issuecomment-1279133120
-[usn]: https://github.com/fsnotify/fsnotify/issues/53#issuecomment-1279829847
-[aix branch]: https://github.com/fsnotify/fsnotify/issues/353#issuecomment-1284590129
-
-Usage
------
-A basic example:
-
-```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{})
-}
-```
-
-Some more examples can be found in [cmd/fsnotify](cmd/fsnotify), which can be
-run with:
-
- % go run ./cmd/fsnotify
-
-Further detailed documentation can be found in godoc:
-https://pkg.go.dev/github.com/fsnotify/fsnotify
-
-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.
-
-### Are subdirectories watched?
-No, you must add watches for any directory you want to watch (a recursive
-watcher is on the roadmap: [#18]).
-
-[#18]: https://github.com/fsnotify/fsnotify/issues/18
-
-### Do I have to watch the Error and Event channels in a goroutine?
-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).
-
-### Why don't notifications work with NFS, SMB, FUSE, /proc, or /sys?
-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.
-
-[#9]: https://github.com/fsnotify/fsnotify/issues/9
-
-### Why do I get many Chmod events?
-Some programs may generate a lot of attribute changes; for example Spotlight on
-macOS, anti-virus programs, backup applications, and some others are known to do
-this. As a rule, it's typically best to ignore Chmod events. They're often not
-useful, and tend to cause problems.
-
-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]).
-
-[#11]: https://github.com/fsnotify/fsnotify/issues/11
-[#15]: https://github.com/fsnotify/fsnotify/issues/15
-
-### Watching a file doesn't work well
-Watching individual files (rather than directories) is generally not recommended
-as many programs (especially editors) update files atomically: it will write to
-a temporary file which is then moved to to destination, overwriting the original
-(or some variant thereof). The watcher on the original file is now lost, as that
-no longer exists.
-
-The upshot of this is that a power failure or crash won't leave a half-written
-file.
-
-Watch the parent directory and use `Event.Name` to filter out files you're not
-interested in. There is an example of this in `cmd/fsnotify/file.go`.
-
-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 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 (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.
-
-The sysctl variables `kern.maxfiles` and `kern.maxfilesperproc` can be used to
-control the maximum number of open files.
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_fen.go b/vendor/github.com/fsnotify/fsnotify/backend_fen.go
deleted file mode 100644
index 28497f1dd..000000000
--- a/vendor/github.com/fsnotify/fsnotify/backend_fen.go
+++ /dev/null
@@ -1,640 +0,0 @@
-//go:build solaris
-// +build solaris
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "sync"
-
- "golang.org/x/sys/unix"
-)
-
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
- Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
- Errors chan error
-
- mu sync.Mutex
- port *unix.EventPort
- done chan struct{} // Channel for sending a "quit message" to the reader goroutine
- dirs map[string]struct{} // Explicitly watched directories
- watches map[string]struct{} // Explicitly watched non-directories
-}
-
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
-}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
- w := &Watcher{
- Events: make(chan Event, sz),
- Errors: make(chan error),
- dirs: make(map[string]struct{}),
- watches: make(map[string]struct{}),
- done: make(chan struct{}),
- }
-
- var err error
- w.port, err = unix.NewEventPort()
- if err != nil {
- return nil, fmt.Errorf("fsnotify.NewWatcher: %w", err)
- }
-
- go w.readEvents()
- return w, nil
-}
-
-// sendEvent attempts to send an event to the user, returning true if the event
-// was put in the channel successfully and false if the watcher has been closed.
-func (w *Watcher) sendEvent(name string, op Op) (sent bool) {
- select {
- case w.Events <- Event{Name: name, Op: op}:
- return true
- case <-w.done:
- return false
- }
-}
-
-// sendError attempts to send an error to the user, returning true if the error
-// was put in the channel successfully and false if the watcher has been closed.
-func (w *Watcher) sendError(err error) (sent bool) {
- select {
- case w.Errors <- err:
- return true
- case <-w.done:
- return false
- }
-}
-
-func (w *Watcher) isClosed() bool {
- select {
- case <-w.done:
- return true
- default:
- return false
- }
-}
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- // Take the lock used by associateFile to prevent lingering events from
- // being processed after the close
- w.mu.Lock()
- defer w.mu.Unlock()
- if w.isClosed() {
- return nil
- }
- close(w.done)
- return w.port.Close()
-}
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
- if w.isClosed() {
- return ErrClosed
- }
- if w.port.PathIsWatched(name) {
- return nil
- }
-
- _ = getOptions(opts...)
-
- // Currently we resolve symlinks that were explicitly requested to be
- // watched. Otherwise we would use LStat here.
- stat, err := os.Stat(name)
- if err != nil {
- return err
- }
-
- // Associate all files in the directory.
- if stat.IsDir() {
- err := w.handleDirectory(name, stat, true, w.associateFile)
- if err != nil {
- return err
- }
-
- w.mu.Lock()
- w.dirs[name] = struct{}{}
- w.mu.Unlock()
- return nil
- }
-
- err = w.associateFile(name, stat, true)
- if err != nil {
- return err
- }
-
- w.mu.Lock()
- w.watches[name] = struct{}{}
- w.mu.Unlock()
- return nil
-}
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
- if w.isClosed() {
- return nil
- }
- if !w.port.PathIsWatched(name) {
- return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
- }
-
- // The user has expressed an intent. Immediately remove this name from
- // whichever watch list it might be in. If it's not in there the delete
- // doesn't cause harm.
- w.mu.Lock()
- delete(w.watches, name)
- delete(w.dirs, name)
- w.mu.Unlock()
-
- stat, err := os.Stat(name)
- if err != nil {
- return err
- }
-
- // Remove associations for every file in the directory.
- if stat.IsDir() {
- err := w.handleDirectory(name, stat, false, w.dissociateFile)
- if err != nil {
- return err
- }
- return nil
- }
-
- err = w.port.DissociatePath(name)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// readEvents contains the main loop that runs in a goroutine watching for events.
-func (w *Watcher) readEvents() {
- // If this function returns, the watcher has been closed and we can close
- // these channels
- defer func() {
- close(w.Errors)
- close(w.Events)
- }()
-
- pevents := make([]unix.PortEvent, 8)
- for {
- count, err := w.port.Get(pevents, 1, nil)
- if err != nil && err != unix.ETIME {
- // Interrupted system call (count should be 0) ignore and continue
- if errors.Is(err, unix.EINTR) && count == 0 {
- continue
- }
- // Get failed because we called w.Close()
- if errors.Is(err, unix.EBADF) && w.isClosed() {
- return
- }
- // There was an error not caused by calling w.Close()
- if !w.sendError(err) {
- return
- }
- }
-
- p := pevents[:count]
- for _, pevent := range p {
- if pevent.Source != unix.PORT_SOURCE_FILE {
- // Event from unexpected source received; should never happen.
- if !w.sendError(errors.New("Event from unexpected source received")) {
- return
- }
- continue
- }
-
- err = w.handleEvent(&pevent)
- if err != nil {
- if !w.sendError(err) {
- return
- }
- }
- }
- }
-}
-
-func (w *Watcher) handleDirectory(path string, stat os.FileInfo, follow bool, handler func(string, os.FileInfo, bool) error) error {
- files, err := os.ReadDir(path)
- if err != nil {
- return err
- }
-
- // Handle all children of the directory.
- for _, entry := range files {
- finfo, err := entry.Info()
- if err != nil {
- return err
- }
- err = handler(filepath.Join(path, finfo.Name()), finfo, false)
- if err != nil {
- return err
- }
- }
-
- // And finally handle the directory itself.
- return handler(path, stat, follow)
-}
-
-// handleEvent might need to emit more than one fsnotify event if the events
-// bitmap matches more than one event type (e.g. the file was both modified and
-// had the attributes changed between when the association was created and the
-// when event was returned)
-func (w *Watcher) handleEvent(event *unix.PortEvent) error {
- var (
- events = event.Events
- path = event.Path
- fmode = event.Cookie.(os.FileMode)
- reRegister = true
- )
-
- w.mu.Lock()
- _, watchedDir := w.dirs[path]
- _, watchedPath := w.watches[path]
- w.mu.Unlock()
- isWatched := watchedDir || watchedPath
-
- if events&unix.FILE_DELETE != 0 {
- if !w.sendEvent(path, Remove) {
- return nil
- }
- reRegister = false
- }
- if events&unix.FILE_RENAME_FROM != 0 {
- if !w.sendEvent(path, Rename) {
- return nil
- }
- // Don't keep watching the new file name
- reRegister = false
- }
- if events&unix.FILE_RENAME_TO != 0 {
- // We don't report a Rename event for this case, because Rename events
- // are interpreted as referring to the _old_ name of the file, and in
- // this case the event would refer to the new name of the file. This
- // type of rename event is not supported by fsnotify.
-
- // inotify reports a Remove event in this case, so we simulate this
- // here.
- if !w.sendEvent(path, Remove) {
- return nil
- }
- // Don't keep watching the file that was removed
- reRegister = false
- }
-
- // The file is gone, nothing left to do.
- if !reRegister {
- if watchedDir {
- w.mu.Lock()
- delete(w.dirs, path)
- w.mu.Unlock()
- }
- if watchedPath {
- w.mu.Lock()
- delete(w.watches, path)
- w.mu.Unlock()
- }
- return nil
- }
-
- // If we didn't get a deletion the file still exists and we're going to have
- // to watch it again. Let's Stat it now so that we can compare permissions
- // and have what we need to continue watching the file
-
- stat, err := os.Lstat(path)
- if err != nil {
- // This is unexpected, but we should still emit an event. This happens
- // most often on "rm -r" of a subdirectory inside a watched directory We
- // get a modify event of something happening inside, but by the time we
- // get here, the sudirectory is already gone. Clearly we were watching
- // this path but now it is gone. Let's tell the user that it was
- // removed.
- if !w.sendEvent(path, Remove) {
- return nil
- }
- // Suppress extra write events on removed directories; they are not
- // informative and can be confusing.
- return nil
- }
-
- // resolve symlinks that were explicitly watched as we would have at Add()
- // time. this helps suppress spurious Chmod events on watched symlinks
- if isWatched {
- stat, err = os.Stat(path)
- if err != nil {
- // The symlink still exists, but the target is gone. Report the
- // Remove similar to above.
- if !w.sendEvent(path, Remove) {
- return nil
- }
- // Don't return the error
- }
- }
-
- if events&unix.FILE_MODIFIED != 0 {
- if fmode.IsDir() {
- if watchedDir {
- if err := w.updateDirectory(path); err != nil {
- return err
- }
- } else {
- if !w.sendEvent(path, Write) {
- return nil
- }
- }
- } else {
- if !w.sendEvent(path, Write) {
- return nil
- }
- }
- }
- if events&unix.FILE_ATTRIB != 0 && stat != nil {
- // Only send Chmod if perms changed
- if stat.Mode().Perm() != fmode.Perm() {
- if !w.sendEvent(path, Chmod) {
- return nil
- }
- }
- }
-
- if stat != nil {
- // If we get here, it means we've hit an event above that requires us to
- // continue watching the file or directory
- return w.associateFile(path, stat, isWatched)
- }
- return nil
-}
-
-func (w *Watcher) updateDirectory(path string) error {
- // The directory was modified, so we must find unwatched entities and watch
- // them. If something was removed from the directory, nothing will happen,
- // as everything else should still be watched.
- files, err := os.ReadDir(path)
- if err != nil {
- return err
- }
-
- for _, entry := range files {
- path := filepath.Join(path, entry.Name())
- if w.port.PathIsWatched(path) {
- continue
- }
-
- finfo, err := entry.Info()
- if err != nil {
- return err
- }
- err = w.associateFile(path, finfo, false)
- if err != nil {
- if !w.sendError(err) {
- return nil
- }
- }
- if !w.sendEvent(path, Create) {
- return nil
- }
- }
- return nil
-}
-
-func (w *Watcher) associateFile(path string, stat os.FileInfo, follow bool) error {
- if w.isClosed() {
- return ErrClosed
- }
- // This is primarily protecting the call to AssociatePath but it is
- // important and intentional that the call to PathIsWatched is also
- // protected by this mutex. Without this mutex, AssociatePath has been seen
- // to error out that the path is already associated.
- w.mu.Lock()
- defer w.mu.Unlock()
-
- if w.port.PathIsWatched(path) {
- // Remove the old association in favor of this one If we get ENOENT,
- // then while the x/sys/unix wrapper still thought that this path was
- // associated, the underlying event port did not. This call will have
- // cleared up that discrepancy. The most likely cause is that the event
- // has fired but we haven't processed it yet.
- err := w.port.DissociatePath(path)
- if err != nil && err != unix.ENOENT {
- return err
- }
- }
- // FILE_NOFOLLOW means we watch symlinks themselves rather than their
- // targets.
- events := unix.FILE_MODIFIED | unix.FILE_ATTRIB | unix.FILE_NOFOLLOW
- if follow {
- // We *DO* follow symlinks for explicitly watched entries.
- events = unix.FILE_MODIFIED | unix.FILE_ATTRIB
- }
- return w.port.AssociatePath(path, stat,
- events,
- stat.Mode())
-}
-
-func (w *Watcher) dissociateFile(path string, stat os.FileInfo, unused bool) error {
- if !w.port.PathIsWatched(path) {
- return nil
- }
- return w.port.DissociatePath(path)
-}
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
- if w.isClosed() {
- return nil
- }
-
- w.mu.Lock()
- defer w.mu.Unlock()
-
- entries := make([]string, 0, len(w.watches)+len(w.dirs))
- for pathname := range w.dirs {
- entries = append(entries, pathname)
- }
- for pathname := range w.watches {
- entries = append(entries, pathname)
- }
-
- return entries
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go
deleted file mode 100644
index 921c1c1e4..000000000
--- a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go
+++ /dev/null
@@ -1,594 +0,0 @@
-//go:build linux && !appengine
-// +build linux,!appengine
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "unsafe"
-
- "golang.org/x/sys/unix"
-)
-
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
- Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
- Errors chan error
-
- // Store fd here as os.File.Read() will no longer return on close after
- // calling Fd(). See: https://github.com/golang/go/issues/26439
- fd int
- inotifyFile *os.File
- watches *watches
- done chan struct{} // Channel for sending a "quit message" to the reader goroutine
- closeMu sync.Mutex
- doneResp chan struct{} // Channel to respond to Close
-}
-
-type (
- watches struct {
- mu sync.RWMutex
- wd map[uint32]*watch // wd → watch
- path map[string]uint32 // pathname → wd
- }
- watch struct {
- wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
- flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)
- path string // Watch path.
- }
-)
-
-func newWatches() *watches {
- return &watches{
- wd: make(map[uint32]*watch),
- path: make(map[string]uint32),
- }
-}
-
-func (w *watches) len() int {
- w.mu.RLock()
- defer w.mu.RUnlock()
- return len(w.wd)
-}
-
-func (w *watches) add(ww *watch) {
- w.mu.Lock()
- defer w.mu.Unlock()
- w.wd[ww.wd] = ww
- w.path[ww.path] = ww.wd
-}
-
-func (w *watches) remove(wd uint32) {
- w.mu.Lock()
- defer w.mu.Unlock()
- delete(w.path, w.wd[wd].path)
- delete(w.wd, wd)
-}
-
-func (w *watches) removePath(path string) (uint32, bool) {
- w.mu.Lock()
- defer w.mu.Unlock()
-
- wd, ok := w.path[path]
- if !ok {
- return 0, false
- }
-
- delete(w.path, path)
- delete(w.wd, wd)
-
- return wd, true
-}
-
-func (w *watches) byPath(path string) *watch {
- w.mu.RLock()
- defer w.mu.RUnlock()
- return w.wd[w.path[path]]
-}
-
-func (w *watches) byWd(wd uint32) *watch {
- w.mu.RLock()
- defer w.mu.RUnlock()
- return w.wd[wd]
-}
-
-func (w *watches) updatePath(path string, f func(*watch) (*watch, error)) error {
- w.mu.Lock()
- defer w.mu.Unlock()
-
- var existing *watch
- wd, ok := w.path[path]
- if ok {
- existing = w.wd[wd]
- }
-
- upd, err := f(existing)
- if err != nil {
- return err
- }
- if upd != nil {
- w.wd[upd.wd] = upd
- w.path[upd.path] = upd.wd
-
- if upd.wd != wd {
- delete(w.wd, wd)
- }
- }
-
- return nil
-}
-
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
-}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
- // Need to set nonblocking mode for SetDeadline to work, otherwise blocking
- // I/O operations won't terminate on close.
- fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC | unix.IN_NONBLOCK)
- if fd == -1 {
- return nil, errno
- }
-
- w := &Watcher{
- fd: fd,
- inotifyFile: os.NewFile(uintptr(fd), ""),
- watches: newWatches(),
- Events: make(chan Event, sz),
- Errors: make(chan error),
- done: make(chan struct{}),
- doneResp: make(chan struct{}),
- }
-
- go w.readEvents()
- return w, nil
-}
-
-// Returns true if the event was sent, or false if watcher is closed.
-func (w *Watcher) sendEvent(e Event) bool {
- select {
- case w.Events <- e:
- return true
- case <-w.done:
- return false
- }
-}
-
-// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
- select {
- case w.Errors <- err:
- return true
- case <-w.done:
- return false
- }
-}
-
-func (w *Watcher) isClosed() bool {
- select {
- case <-w.done:
- return true
- default:
- return false
- }
-}
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- w.closeMu.Lock()
- if w.isClosed() {
- w.closeMu.Unlock()
- return nil
- }
- close(w.done)
- w.closeMu.Unlock()
-
- // Causes any blocking reads to return with an error, provided the file
- // still supports deadline operations.
- err := w.inotifyFile.Close()
- if err != nil {
- return err
- }
-
- // Wait for goroutine to close
- <-w.doneResp
-
- return nil
-}
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
- if w.isClosed() {
- return ErrClosed
- }
-
- name = filepath.Clean(name)
- _ = getOptions(opts...)
-
- var flags uint32 = unix.IN_MOVED_TO | unix.IN_MOVED_FROM |
- unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY |
- unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF
-
- return w.watches.updatePath(name, func(existing *watch) (*watch, error) {
- if existing != nil {
- flags |= existing.flags | unix.IN_MASK_ADD
- }
-
- wd, err := unix.InotifyAddWatch(w.fd, name, flags)
- if wd == -1 {
- return nil, err
- }
-
- if existing == nil {
- return &watch{
- wd: uint32(wd),
- path: name,
- flags: flags,
- }, nil
- }
-
- existing.wd = uint32(wd)
- existing.flags = flags
- return existing, nil
- })
-}
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
- if w.isClosed() {
- return nil
- }
- return w.remove(filepath.Clean(name))
-}
-
-func (w *Watcher) remove(name string) error {
- wd, ok := w.watches.removePath(name)
- if !ok {
- return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
- }
-
- success, errno := unix.InotifyRmWatch(w.fd, wd)
- if success == -1 {
- // TODO: Perhaps it's not helpful to return an error here in every case;
- // The only two possible errors are:
- //
- // - EBADF, which happens when w.fd is not a valid file descriptor
- // of any kind.
- // - EINVAL, which is when fd is not an inotify descriptor or wd
- // is not a valid watch descriptor. Watch descriptors are
- // invalidated when they are removed explicitly or implicitly;
- // explicitly by inotify_rm_watch, implicitly when the file they
- // are watching is deleted.
- return errno
- }
- return nil
-}
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
- if w.isClosed() {
- return nil
- }
-
- entries := make([]string, 0, w.watches.len())
- w.watches.mu.RLock()
- for pathname := range w.watches.path {
- entries = append(entries, pathname)
- }
- w.watches.mu.RUnlock()
-
- return entries
-}
-
-// readEvents reads from the inotify file descriptor, converts the
-// received events into Event objects and sends them via the Events channel
-func (w *Watcher) readEvents() {
- defer func() {
- close(w.doneResp)
- close(w.Errors)
- close(w.Events)
- }()
-
- var (
- buf [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
- errno error // Syscall errno
- )
- for {
- // See if we have been closed.
- if w.isClosed() {
- return
- }
-
- n, err := w.inotifyFile.Read(buf[:])
- switch {
- case errors.Unwrap(err) == os.ErrClosed:
- return
- case err != nil:
- if !w.sendError(err) {
- return
- }
- continue
- }
-
- if n < unix.SizeofInotifyEvent {
- var err error
- if n == 0 {
- err = io.EOF // If EOF is received. This should really never happen.
- } else if n < 0 {
- err = errno // If an error occurred while reading.
- } else {
- err = errors.New("notify: short read in readEvents()") // Read was too short.
- }
- if !w.sendError(err) {
- return
- }
- continue
- }
-
- var offset uint32
- // We don't know how many events we just read into the buffer
- // While the offset points to at least one whole event...
- for offset <= uint32(n-unix.SizeofInotifyEvent) {
- var (
- // Point "raw" to the event in the buffer
- raw = (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))
- mask = uint32(raw.Mask)
- nameLen = uint32(raw.Len)
- )
-
- if mask&unix.IN_Q_OVERFLOW != 0 {
- if !w.sendError(ErrEventOverflow) {
- return
- }
- }
-
- // If the event happened to the watched directory or the watched file, the kernel
- // doesn't append the filename to the event, but we would like to always fill the
- // the "Name" field with a valid filename. We retrieve the path of the watch from
- // the "paths" map.
- watch := w.watches.byWd(uint32(raw.Wd))
-
- // inotify will automatically remove the watch on deletes; just need
- // to clean our state here.
- if watch != nil && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF {
- w.watches.remove(watch.wd)
- }
- // We can't really update the state when a watched path is moved;
- // only IN_MOVE_SELF is sent and not IN_MOVED_{FROM,TO}. So remove
- // the watch.
- if watch != nil && mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF {
- err := w.remove(watch.path)
- if err != nil && !errors.Is(err, ErrNonExistentWatch) {
- if !w.sendError(err) {
- return
- }
- }
- }
-
- var name string
- if watch != nil {
- name = watch.path
- }
- if nameLen > 0 {
- // Point "bytes" at the first byte of the filename
- bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen]
- // The filename is padded with NULL bytes. TrimRight() gets rid of those.
- name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
- }
-
- event := w.newEvent(name, mask)
-
- // Send the events that are not ignored on the events channel
- if mask&unix.IN_IGNORED == 0 {
- if !w.sendEvent(event) {
- return
- }
- }
-
- // Move to the next event in the buffer
- offset += unix.SizeofInotifyEvent + nameLen
- }
- }
-}
-
-// newEvent returns an platform-independent Event based on an inotify mask.
-func (w *Watcher) newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {
- e.Op |= Create
- }
- if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE {
- e.Op |= Remove
- }
- if mask&unix.IN_MODIFY == unix.IN_MODIFY {
- e.Op |= Write
- }
- if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {
- e.Op |= Rename
- }
- if mask&unix.IN_ATTRIB == unix.IN_ATTRIB {
- e.Op |= Chmod
- }
- return e
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go
deleted file mode 100644
index 063a0915a..000000000
--- a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go
+++ /dev/null
@@ -1,782 +0,0 @@
-//go:build freebsd || openbsd || netbsd || dragonfly || darwin
-// +build freebsd openbsd netbsd dragonfly darwin
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "sync"
-
- "golang.org/x/sys/unix"
-)
-
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
- Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
- Errors chan error
-
- done chan struct{}
- kq int // File descriptor (as returned by the kqueue() syscall).
- closepipe [2]int // Pipe used for closing.
- mu sync.Mutex // Protects access to watcher data
- watches map[string]int // Watched file descriptors (key: path).
- watchesByDir map[string]map[int]struct{} // Watched file descriptors indexed by the parent directory (key: dirname(path)).
- userWatches map[string]struct{} // Watches added with Watcher.Add()
- dirFlags map[string]uint32 // Watched directories to fflags used in kqueue.
- paths map[int]pathInfo // File descriptors to path names for processing kqueue events.
- fileExists map[string]struct{} // Keep track of if we know this file exists (to stop duplicate create events).
- isClosed bool // Set to true when Close() is first called
-}
-
-type pathInfo struct {
- name string
- isDir bool
-}
-
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(0)
-}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
- kq, closepipe, err := newKqueue()
- if err != nil {
- return nil, err
- }
-
- w := &Watcher{
- kq: kq,
- closepipe: closepipe,
- watches: make(map[string]int),
- watchesByDir: make(map[string]map[int]struct{}),
- dirFlags: make(map[string]uint32),
- paths: make(map[int]pathInfo),
- fileExists: make(map[string]struct{}),
- userWatches: make(map[string]struct{}),
- Events: make(chan Event, sz),
- Errors: make(chan error),
- done: make(chan struct{}),
- }
-
- go w.readEvents()
- return w, nil
-}
-
-// newKqueue creates a new kernel event queue and returns a descriptor.
-//
-// This registers a new event on closepipe, which will trigger an event when
-// it's closed. This way we can use kevent() without timeout/polling; without
-// the closepipe, it would block forever and we wouldn't be able to stop it at
-// all.
-func newKqueue() (kq int, closepipe [2]int, err error) {
- kq, err = unix.Kqueue()
- if kq == -1 {
- return kq, closepipe, err
- }
-
- // Register the close pipe.
- err = unix.Pipe(closepipe[:])
- if err != nil {
- unix.Close(kq)
- return kq, closepipe, err
- }
-
- // Register changes to listen on the closepipe.
- changes := make([]unix.Kevent_t, 1)
- // SetKevent converts int to the platform-specific types.
- unix.SetKevent(&changes[0], closepipe[0], unix.EVFILT_READ,
- unix.EV_ADD|unix.EV_ENABLE|unix.EV_ONESHOT)
-
- ok, err := unix.Kevent(kq, changes, nil, nil)
- if ok == -1 {
- unix.Close(kq)
- unix.Close(closepipe[0])
- unix.Close(closepipe[1])
- return kq, closepipe, err
- }
- return kq, closepipe, nil
-}
-
-// Returns true if the event was sent, or false if watcher is closed.
-func (w *Watcher) sendEvent(e Event) bool {
- select {
- case w.Events <- e:
- return true
- case <-w.done:
- return false
- }
-}
-
-// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
- select {
- case w.Errors <- err:
- return true
- case <-w.done:
- return false
- }
-}
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
- return nil
- }
- w.isClosed = true
-
- // copy paths to remove while locked
- pathsToRemove := make([]string, 0, len(w.watches))
- for name := range w.watches {
- pathsToRemove = append(pathsToRemove, name)
- }
- w.mu.Unlock() // Unlock before calling Remove, which also locks
- for _, name := range pathsToRemove {
- w.Remove(name)
- }
-
- // Send "quit" message to the reader goroutine.
- unix.Close(w.closepipe[1])
- close(w.done)
-
- return nil
-}
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
- _ = getOptions(opts...)
-
- w.mu.Lock()
- w.userWatches[name] = struct{}{}
- w.mu.Unlock()
- _, err := w.addWatch(name, noteAllEvents)
- return err
-}
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
- return w.remove(name, true)
-}
-
-func (w *Watcher) remove(name string, unwatchFiles bool) error {
- name = filepath.Clean(name)
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
- return nil
- }
- watchfd, ok := w.watches[name]
- w.mu.Unlock()
- if !ok {
- return fmt.Errorf("%w: %s", ErrNonExistentWatch, name)
- }
-
- err := w.register([]int{watchfd}, unix.EV_DELETE, 0)
- if err != nil {
- return err
- }
-
- unix.Close(watchfd)
-
- w.mu.Lock()
- isDir := w.paths[watchfd].isDir
- delete(w.watches, name)
- delete(w.userWatches, name)
-
- parentName := filepath.Dir(name)
- delete(w.watchesByDir[parentName], watchfd)
-
- if len(w.watchesByDir[parentName]) == 0 {
- delete(w.watchesByDir, parentName)
- }
-
- delete(w.paths, watchfd)
- delete(w.dirFlags, name)
- delete(w.fileExists, name)
- w.mu.Unlock()
-
- // Find all watched paths that are in this directory that are not external.
- if unwatchFiles && isDir {
- var pathsToRemove []string
- w.mu.Lock()
- for fd := range w.watchesByDir[name] {
- path := w.paths[fd]
- if _, ok := w.userWatches[path.name]; !ok {
- pathsToRemove = append(pathsToRemove, path.name)
- }
- }
- w.mu.Unlock()
- for _, name := range pathsToRemove {
- // Since these are internal, not much sense in propagating error to
- // the user, as that will just confuse them with an error about a
- // path they did not explicitly watch themselves.
- w.Remove(name)
- }
- }
- return nil
-}
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
- w.mu.Lock()
- defer w.mu.Unlock()
- if w.isClosed {
- return nil
- }
-
- entries := make([]string, 0, len(w.userWatches))
- for pathname := range w.userWatches {
- entries = append(entries, pathname)
- }
-
- return entries
-}
-
-// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
-const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME
-
-// addWatch adds name to the watched file set; the flags are interpreted as
-// described in kevent(2).
-//
-// Returns the real path to the file which was added, with symlinks resolved.
-func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
- var isDir bool
- name = filepath.Clean(name)
-
- w.mu.Lock()
- if w.isClosed {
- w.mu.Unlock()
- return "", ErrClosed
- }
- watchfd, alreadyWatching := w.watches[name]
- // We already have a watch, but we can still override flags.
- if alreadyWatching {
- isDir = w.paths[watchfd].isDir
- }
- w.mu.Unlock()
-
- if !alreadyWatching {
- fi, err := os.Lstat(name)
- if err != nil {
- return "", err
- }
-
- // Don't watch sockets or named pipes
- if (fi.Mode()&os.ModeSocket == os.ModeSocket) || (fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe) {
- return "", nil
- }
-
- // Follow Symlinks.
- if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
- link, err := os.Readlink(name)
- if err != nil {
- // Return nil because Linux can add unresolvable symlinks to the
- // watch list without problems, so maintain consistency with
- // that. There will be no file events for broken symlinks.
- // TODO: more specific check; returns os.PathError; ENOENT?
- return "", nil
- }
-
- w.mu.Lock()
- _, alreadyWatching = w.watches[link]
- w.mu.Unlock()
-
- if alreadyWatching {
- // Add to watches so we don't get spurious Create events later
- // on when we diff the directories.
- w.watches[name] = 0
- w.fileExists[name] = struct{}{}
- return link, nil
- }
-
- name = link
- fi, err = os.Lstat(name)
- if err != nil {
- return "", nil
- }
- }
-
- // Retry on EINTR; open() can return EINTR in practice on macOS.
- // See #354, and Go issues 11180 and 39237.
- for {
- watchfd, err = unix.Open(name, openMode, 0)
- if err == nil {
- break
- }
- if errors.Is(err, unix.EINTR) {
- continue
- }
-
- return "", err
- }
-
- isDir = fi.IsDir()
- }
-
- err := w.register([]int{watchfd}, unix.EV_ADD|unix.EV_CLEAR|unix.EV_ENABLE, flags)
- if err != nil {
- unix.Close(watchfd)
- return "", err
- }
-
- if !alreadyWatching {
- w.mu.Lock()
- parentName := filepath.Dir(name)
- w.watches[name] = watchfd
-
- watchesByDir, ok := w.watchesByDir[parentName]
- if !ok {
- watchesByDir = make(map[int]struct{}, 1)
- w.watchesByDir[parentName] = watchesByDir
- }
- watchesByDir[watchfd] = struct{}{}
- w.paths[watchfd] = pathInfo{name: name, isDir: isDir}
- w.mu.Unlock()
- }
-
- if isDir {
- // Watch the directory if it has not been watched before, or if it was
- // watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
- w.mu.Lock()
-
- watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
- (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
- // Store flags so this watch can be updated later
- w.dirFlags[name] = flags
- w.mu.Unlock()
-
- if watchDir {
- if err := w.watchDirectoryFiles(name); err != nil {
- return "", err
- }
- }
- }
- return name, nil
-}
-
-// readEvents reads from kqueue and converts the received kevents into
-// Event values that it sends down the Events channel.
-func (w *Watcher) readEvents() {
- defer func() {
- close(w.Events)
- close(w.Errors)
- _ = unix.Close(w.kq)
- unix.Close(w.closepipe[0])
- }()
-
- eventBuffer := make([]unix.Kevent_t, 10)
- for closed := false; !closed; {
- kevents, err := w.read(eventBuffer)
- // EINTR is okay, the syscall was interrupted before timeout expired.
- if err != nil && err != unix.EINTR {
- if !w.sendError(fmt.Errorf("fsnotify.readEvents: %w", err)) {
- closed = true
- }
- continue
- }
-
- // Flush the events we received to the Events channel
- for _, kevent := range kevents {
- var (
- watchfd = int(kevent.Ident)
- mask = uint32(kevent.Fflags)
- )
-
- // Shut down the loop when the pipe is closed, but only after all
- // other events have been processed.
- if watchfd == w.closepipe[0] {
- closed = true
- continue
- }
-
- w.mu.Lock()
- path := w.paths[watchfd]
- w.mu.Unlock()
-
- event := w.newEvent(path.name, mask)
-
- if event.Has(Rename) || event.Has(Remove) {
- w.remove(event.Name, false)
- w.mu.Lock()
- delete(w.fileExists, event.Name)
- w.mu.Unlock()
- }
-
- if path.isDir && event.Has(Write) && !event.Has(Remove) {
- w.sendDirectoryChangeEvents(event.Name)
- } else {
- if !w.sendEvent(event) {
- closed = true
- continue
- }
- }
-
- if event.Has(Remove) {
- // Look for a file that may have overwritten this; for example,
- // mv f1 f2 will delete f2, then create f2.
- if path.isDir {
- fileDir := filepath.Clean(event.Name)
- w.mu.Lock()
- _, found := w.watches[fileDir]
- w.mu.Unlock()
- if found {
- err := w.sendDirectoryChangeEvents(fileDir)
- if err != nil {
- if !w.sendError(err) {
- closed = true
- }
- }
- }
- } else {
- filePath := filepath.Clean(event.Name)
- if fi, err := os.Lstat(filePath); err == nil {
- err := w.sendFileCreatedEventIfNew(filePath, fi)
- if err != nil {
- if !w.sendError(err) {
- closed = true
- }
- }
- }
- }
- }
- }
- }
-}
-
-// newEvent returns an platform-independent Event based on kqueue Fflags.
-func (w *Watcher) newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
- e.Op |= Remove
- }
- if mask&unix.NOTE_WRITE == unix.NOTE_WRITE {
- e.Op |= Write
- }
- if mask&unix.NOTE_RENAME == unix.NOTE_RENAME {
- e.Op |= Rename
- }
- if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {
- e.Op |= Chmod
- }
- // No point sending a write and delete event at the same time: if it's gone,
- // then it's gone.
- if e.Op.Has(Write) && e.Op.Has(Remove) {
- e.Op &^= Write
- }
- return e
-}
-
-// watchDirectoryFiles to mimic inotify when adding a watch on a directory
-func (w *Watcher) watchDirectoryFiles(dirPath string) error {
- // Get all files
- files, err := os.ReadDir(dirPath)
- if err != nil {
- return err
- }
-
- for _, f := range files {
- path := filepath.Join(dirPath, f.Name())
-
- fi, err := f.Info()
- if err != nil {
- return fmt.Errorf("%q: %w", path, err)
- }
-
- cleanPath, err := w.internalWatch(path, fi)
- if err != nil {
- // No permission to read the file; that's not a problem: just skip.
- // But do add it to w.fileExists to prevent it from being picked up
- // as a "new" file later (it still shows up in the directory
- // listing).
- switch {
- case errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM):
- cleanPath = filepath.Clean(path)
- default:
- return fmt.Errorf("%q: %w", path, err)
- }
- }
-
- w.mu.Lock()
- w.fileExists[cleanPath] = struct{}{}
- w.mu.Unlock()
- }
-
- return nil
-}
-
-// Search the directory for new files and send an event for them.
-//
-// This functionality is to have the BSD watcher match the inotify, which sends
-// a create event for files created in a watched directory.
-func (w *Watcher) sendDirectoryChangeEvents(dir string) error {
- files, err := os.ReadDir(dir)
- if err != nil {
- // Directory no longer exists: we can ignore this safely. kqueue will
- // still give us the correct events.
- if errors.Is(err, os.ErrNotExist) {
- return nil
- }
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
- }
-
- for _, f := range files {
- fi, err := f.Info()
- if err != nil {
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
- }
-
- err = w.sendFileCreatedEventIfNew(filepath.Join(dir, fi.Name()), fi)
- if err != nil {
- // Don't need to send an error if this file isn't readable.
- if errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM) {
- return nil
- }
- return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)
- }
- }
- return nil
-}
-
-// sendFileCreatedEvent sends a create event if the file isn't already being tracked.
-func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fi os.FileInfo) (err error) {
- w.mu.Lock()
- _, doesExist := w.fileExists[filePath]
- w.mu.Unlock()
- if !doesExist {
- if !w.sendEvent(Event{Name: filePath, Op: Create}) {
- return
- }
- }
-
- // like watchDirectoryFiles (but without doing another ReadDir)
- filePath, err = w.internalWatch(filePath, fi)
- if err != nil {
- return err
- }
-
- w.mu.Lock()
- w.fileExists[filePath] = struct{}{}
- w.mu.Unlock()
-
- return nil
-}
-
-func (w *Watcher) internalWatch(name string, fi os.FileInfo) (string, error) {
- if fi.IsDir() {
- // mimic Linux providing delete events for subdirectories, but preserve
- // the flags used if currently watching subdirectory
- w.mu.Lock()
- flags := w.dirFlags[name]
- w.mu.Unlock()
-
- flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
- return w.addWatch(name, flags)
- }
-
- // watch file to mimic Linux inotify
- return w.addWatch(name, noteAllEvents)
-}
-
-// Register events with the queue.
-func (w *Watcher) register(fds []int, flags int, fflags uint32) error {
- changes := make([]unix.Kevent_t, len(fds))
- for i, fd := range fds {
- // SetKevent converts int to the platform-specific types.
- unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)
- changes[i].Fflags = fflags
- }
-
- // Register the events.
- success, err := unix.Kevent(w.kq, changes, nil, nil)
- if success == -1 {
- return err
- }
- return nil
-}
-
-// read retrieves pending events, or waits until an event occurs.
-func (w *Watcher) read(events []unix.Kevent_t) ([]unix.Kevent_t, error) {
- n, err := unix.Kevent(w.kq, nil, events, nil)
- if err != nil {
- return nil, err
- }
- return events[0:n], nil
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_other.go b/vendor/github.com/fsnotify/fsnotify/backend_other.go
deleted file mode 100644
index d34a23c01..000000000
--- a/vendor/github.com/fsnotify/fsnotify/backend_other.go
+++ /dev/null
@@ -1,205 +0,0 @@
-//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows)
-// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows
-
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
-
-package fsnotify
-
-import "errors"
-
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
- Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
- Errors chan error
-}
-
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return nil, errors.New("fsnotify not supported on the current platform")
-}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) { return NewWatcher() }
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error { return nil }
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string { return nil }
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return nil }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error { return nil }
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error { return nil }
diff --git a/vendor/github.com/fsnotify/fsnotify/backend_windows.go b/vendor/github.com/fsnotify/fsnotify/backend_windows.go
deleted file mode 100644
index 9bc91e5d6..000000000
--- a/vendor/github.com/fsnotify/fsnotify/backend_windows.go
+++ /dev/null
@@ -1,827 +0,0 @@
-//go:build windows
-// +build windows
-
-// Windows backend based on ReadDirectoryChangesW()
-//
-// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw
-//
-// Note: the documentation on the Watcher type and methods is generated from
-// mkdoc.zsh
-
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "reflect"
- "runtime"
- "strings"
- "sync"
- "unsafe"
-
- "golang.org/x/sys/windows"
-)
-
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\path\to\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-type Watcher struct {
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
- Events chan Event
-
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
- Errors chan error
-
- port windows.Handle // Handle to completion port
- input chan *input // Inputs to the reader are sent on this channel
- quit chan chan<- error
-
- mu sync.Mutex // Protects access to watches, closed
- watches watchMap // Map of watches (key: i-number)
- closed bool // Set to true when Close() is first called
-}
-
-// NewWatcher creates a new Watcher.
-func NewWatcher() (*Watcher, error) {
- return NewBufferedWatcher(50)
-}
-
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-func NewBufferedWatcher(sz uint) (*Watcher, error) {
- port, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0)
- if err != nil {
- return nil, os.NewSyscallError("CreateIoCompletionPort", err)
- }
- w := &Watcher{
- port: port,
- watches: make(watchMap),
- input: make(chan *input, 1),
- Events: make(chan Event, sz),
- Errors: make(chan error),
- quit: make(chan chan<- error, 1),
- }
- go w.readEvents()
- return w, nil
-}
-
-func (w *Watcher) isClosed() bool {
- w.mu.Lock()
- defer w.mu.Unlock()
- return w.closed
-}
-
-func (w *Watcher) sendEvent(name string, mask uint64) bool {
- if mask == 0 {
- return false
- }
-
- event := w.newEvent(name, uint32(mask))
- select {
- case ch := <-w.quit:
- w.quit <- ch
- case w.Events <- event:
- }
- return true
-}
-
-// Returns true if the error was sent, or false if watcher is closed.
-func (w *Watcher) sendError(err error) bool {
- select {
- case w.Errors <- err:
- return true
- case <-w.quit:
- }
- return false
-}
-
-// Close removes all watches and closes the Events channel.
-func (w *Watcher) Close() error {
- if w.isClosed() {
- return nil
- }
-
- w.mu.Lock()
- w.closed = true
- w.mu.Unlock()
-
- // Send "quit" message to the reader goroutine
- ch := make(chan error)
- w.quit <- ch
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-ch
-}
-
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-func (w *Watcher) Add(name string) error { return w.AddWith(name) }
-
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-func (w *Watcher) AddWith(name string, opts ...addOpt) error {
- if w.isClosed() {
- return ErrClosed
- }
-
- with := getOptions(opts...)
- if with.bufsize < 4096 {
- return fmt.Errorf("fsnotify.WithBufferSize: buffer size cannot be smaller than 4096 bytes")
- }
-
- in := &input{
- op: opAddWatch,
- path: filepath.Clean(name),
- flags: sysFSALLEVENTS,
- reply: make(chan error),
- bufsize: with.bufsize,
- }
- w.input <- in
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-in.reply
-}
-
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) Remove(name string) error {
- if w.isClosed() {
- return nil
- }
-
- in := &input{
- op: opRemoveWatch,
- path: filepath.Clean(name),
- reply: make(chan error),
- }
- w.input <- in
- if err := w.wakeupReader(); err != nil {
- return err
- }
- return <-in.reply
-}
-
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-func (w *Watcher) WatchList() []string {
- if w.isClosed() {
- return nil
- }
-
- w.mu.Lock()
- defer w.mu.Unlock()
-
- entries := make([]string, 0, len(w.watches))
- for _, entry := range w.watches {
- for _, watchEntry := range entry {
- entries = append(entries, watchEntry.path)
- }
- }
-
- return entries
-}
-
-// These options are from the old golang.org/x/exp/winfsnotify, where you could
-// add various options to the watch. This has long since been removed.
-//
-// The "sys" in the name is misleading as they're not part of any "system".
-//
-// This should all be removed at some point, and just use windows.FILE_NOTIFY_*
-const (
- sysFSALLEVENTS = 0xfff
- sysFSCREATE = 0x100
- sysFSDELETE = 0x200
- sysFSDELETESELF = 0x400
- sysFSMODIFY = 0x2
- sysFSMOVE = 0xc0
- sysFSMOVEDFROM = 0x40
- sysFSMOVEDTO = 0x80
- sysFSMOVESELF = 0x800
- sysFSIGNORED = 0x8000
-)
-
-func (w *Watcher) newEvent(name string, mask uint32) Event {
- e := Event{Name: name}
- if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO {
- e.Op |= Create
- }
- if mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF {
- e.Op |= Remove
- }
- if mask&sysFSMODIFY == sysFSMODIFY {
- e.Op |= Write
- }
- if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM {
- e.Op |= Rename
- }
- return e
-}
-
-const (
- opAddWatch = iota
- opRemoveWatch
-)
-
-const (
- provisional uint64 = 1 << (32 + iota)
-)
-
-type input struct {
- op int
- path string
- flags uint32
- bufsize int
- reply chan error
-}
-
-type inode struct {
- handle windows.Handle
- volume uint32
- index uint64
-}
-
-type watch struct {
- ov windows.Overlapped
- ino *inode // i-number
- recurse bool // Recursive watch?
- path string // Directory path
- mask uint64 // Directory itself is being watched with these notify flags
- names map[string]uint64 // Map of names being watched and their notify flags
- rename string // Remembers the old name while renaming a file
- buf []byte // buffer, allocated later
-}
-
-type (
- indexMap map[uint64]*watch
- watchMap map[uint32]indexMap
-)
-
-func (w *Watcher) wakeupReader() error {
- err := windows.PostQueuedCompletionStatus(w.port, 0, 0, nil)
- if err != nil {
- return os.NewSyscallError("PostQueuedCompletionStatus", err)
- }
- return nil
-}
-
-func (w *Watcher) getDir(pathname string) (dir string, err error) {
- attr, err := windows.GetFileAttributes(windows.StringToUTF16Ptr(pathname))
- if err != nil {
- return "", os.NewSyscallError("GetFileAttributes", err)
- }
- if attr&windows.FILE_ATTRIBUTE_DIRECTORY != 0 {
- dir = pathname
- } else {
- dir, _ = filepath.Split(pathname)
- dir = filepath.Clean(dir)
- }
- return
-}
-
-func (w *Watcher) getIno(path string) (ino *inode, err error) {
- h, err := windows.CreateFile(windows.StringToUTF16Ptr(path),
- windows.FILE_LIST_DIRECTORY,
- windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
- nil, windows.OPEN_EXISTING,
- windows.FILE_FLAG_BACKUP_SEMANTICS|windows.FILE_FLAG_OVERLAPPED, 0)
- if err != nil {
- return nil, os.NewSyscallError("CreateFile", err)
- }
-
- var fi windows.ByHandleFileInformation
- err = windows.GetFileInformationByHandle(h, &fi)
- if err != nil {
- windows.CloseHandle(h)
- return nil, os.NewSyscallError("GetFileInformationByHandle", err)
- }
- ino = &inode{
- handle: h,
- volume: fi.VolumeSerialNumber,
- index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),
- }
- return ino, nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) get(ino *inode) *watch {
- if i := m[ino.volume]; i != nil {
- return i[ino.index]
- }
- return nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) set(ino *inode, watch *watch) {
- i := m[ino.volume]
- if i == nil {
- i = make(indexMap)
- m[ino.volume] = i
- }
- i[ino.index] = watch
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) addWatch(pathname string, flags uint64, bufsize int) error {
- //pathname, recurse := recursivePath(pathname)
- recurse := false
-
- dir, err := w.getDir(pathname)
- if err != nil {
- return err
- }
-
- ino, err := w.getIno(dir)
- if err != nil {
- return err
- }
- w.mu.Lock()
- watchEntry := w.watches.get(ino)
- w.mu.Unlock()
- if watchEntry == nil {
- _, err := windows.CreateIoCompletionPort(ino.handle, w.port, 0, 0)
- if err != nil {
- windows.CloseHandle(ino.handle)
- return os.NewSyscallError("CreateIoCompletionPort", err)
- }
- watchEntry = &watch{
- ino: ino,
- path: dir,
- names: make(map[string]uint64),
- recurse: recurse,
- buf: make([]byte, bufsize),
- }
- w.mu.Lock()
- w.watches.set(ino, watchEntry)
- w.mu.Unlock()
- flags |= provisional
- } else {
- windows.CloseHandle(ino.handle)
- }
- if pathname == dir {
- watchEntry.mask |= flags
- } else {
- watchEntry.names[filepath.Base(pathname)] |= flags
- }
-
- err = w.startRead(watchEntry)
- if err != nil {
- return err
- }
-
- if pathname == dir {
- watchEntry.mask &= ^provisional
- } else {
- watchEntry.names[filepath.Base(pathname)] &= ^provisional
- }
- return nil
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) remWatch(pathname string) error {
- pathname, recurse := recursivePath(pathname)
-
- dir, err := w.getDir(pathname)
- if err != nil {
- return err
- }
- ino, err := w.getIno(dir)
- if err != nil {
- return err
- }
-
- w.mu.Lock()
- watch := w.watches.get(ino)
- w.mu.Unlock()
-
- if recurse && !watch.recurse {
- return fmt.Errorf("can't use \\... with non-recursive watch %q", pathname)
- }
-
- err = windows.CloseHandle(ino.handle)
- if err != nil {
- w.sendError(os.NewSyscallError("CloseHandle", err))
- }
- if watch == nil {
- return fmt.Errorf("%w: %s", ErrNonExistentWatch, pathname)
- }
- if pathname == dir {
- w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
- watch.mask = 0
- } else {
- name := filepath.Base(pathname)
- w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED)
- delete(watch.names, name)
- }
-
- return w.startRead(watch)
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) deleteWatch(watch *watch) {
- for name, mask := range watch.names {
- if mask&provisional == 0 {
- w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED)
- }
- delete(watch.names, name)
- }
- if watch.mask != 0 {
- if watch.mask&provisional == 0 {
- w.sendEvent(watch.path, watch.mask&sysFSIGNORED)
- }
- watch.mask = 0
- }
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) startRead(watch *watch) error {
- err := windows.CancelIo(watch.ino.handle)
- if err != nil {
- w.sendError(os.NewSyscallError("CancelIo", err))
- w.deleteWatch(watch)
- }
- mask := w.toWindowsFlags(watch.mask)
- for _, m := range watch.names {
- mask |= w.toWindowsFlags(m)
- }
- if mask == 0 {
- err := windows.CloseHandle(watch.ino.handle)
- if err != nil {
- w.sendError(os.NewSyscallError("CloseHandle", err))
- }
- w.mu.Lock()
- delete(w.watches[watch.ino.volume], watch.ino.index)
- w.mu.Unlock()
- return nil
- }
-
- // We need to pass the array, rather than the slice.
- hdr := (*reflect.SliceHeader)(unsafe.Pointer(&watch.buf))
- rdErr := windows.ReadDirectoryChanges(watch.ino.handle,
- (*byte)(unsafe.Pointer(hdr.Data)), uint32(hdr.Len),
- watch.recurse, mask, nil, &watch.ov, 0)
- if rdErr != nil {
- err := os.NewSyscallError("ReadDirectoryChanges", rdErr)
- if rdErr == windows.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
- // Watched directory was probably removed
- w.sendEvent(watch.path, watch.mask&sysFSDELETESELF)
- err = nil
- }
- w.deleteWatch(watch)
- w.startRead(watch)
- return err
- }
- return nil
-}
-
-// readEvents reads from the I/O completion port, converts the
-// received events into Event objects and sends them via the Events channel.
-// Entry point to the I/O thread.
-func (w *Watcher) readEvents() {
- var (
- n uint32
- key uintptr
- ov *windows.Overlapped
- )
- runtime.LockOSThread()
-
- for {
- // This error is handled after the watch == nil check below.
- qErr := windows.GetQueuedCompletionStatus(w.port, &n, &key, &ov, windows.INFINITE)
-
- watch := (*watch)(unsafe.Pointer(ov))
- if watch == nil {
- select {
- case ch := <-w.quit:
- w.mu.Lock()
- var indexes []indexMap
- for _, index := range w.watches {
- indexes = append(indexes, index)
- }
- w.mu.Unlock()
- for _, index := range indexes {
- for _, watch := range index {
- w.deleteWatch(watch)
- w.startRead(watch)
- }
- }
-
- err := windows.CloseHandle(w.port)
- if err != nil {
- err = os.NewSyscallError("CloseHandle", err)
- }
- close(w.Events)
- close(w.Errors)
- ch <- err
- return
- case in := <-w.input:
- switch in.op {
- case opAddWatch:
- in.reply <- w.addWatch(in.path, uint64(in.flags), in.bufsize)
- case opRemoveWatch:
- in.reply <- w.remWatch(in.path)
- }
- default:
- }
- continue
- }
-
- switch qErr {
- case nil:
- // No error
- case windows.ERROR_MORE_DATA:
- if watch == nil {
- w.sendError(errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer"))
- } else {
- // The i/o succeeded but the buffer is full.
- // In theory we should be building up a full packet.
- // In practice we can get away with just carrying on.
- n = uint32(unsafe.Sizeof(watch.buf))
- }
- case windows.ERROR_ACCESS_DENIED:
- // Watched directory was probably removed
- w.sendEvent(watch.path, watch.mask&sysFSDELETESELF)
- w.deleteWatch(watch)
- w.startRead(watch)
- continue
- case windows.ERROR_OPERATION_ABORTED:
- // CancelIo was called on this handle
- continue
- default:
- w.sendError(os.NewSyscallError("GetQueuedCompletionPort", qErr))
- continue
- }
-
- var offset uint32
- for {
- if n == 0 {
- w.sendError(ErrEventOverflow)
- break
- }
-
- // Point "raw" to the event in the buffer
- raw := (*windows.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
-
- // Create a buf that is the size of the path name
- size := int(raw.FileNameLength / 2)
- var buf []uint16
- // TODO: Use unsafe.Slice in Go 1.17; https://stackoverflow.com/questions/51187973
- sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
- sh.Data = uintptr(unsafe.Pointer(&raw.FileName))
- sh.Len = size
- sh.Cap = size
- name := windows.UTF16ToString(buf)
- fullname := filepath.Join(watch.path, name)
-
- var mask uint64
- switch raw.Action {
- case windows.FILE_ACTION_REMOVED:
- mask = sysFSDELETESELF
- case windows.FILE_ACTION_MODIFIED:
- mask = sysFSMODIFY
- case windows.FILE_ACTION_RENAMED_OLD_NAME:
- watch.rename = name
- case windows.FILE_ACTION_RENAMED_NEW_NAME:
- // Update saved path of all sub-watches.
- old := filepath.Join(watch.path, watch.rename)
- w.mu.Lock()
- for _, watchMap := range w.watches {
- for _, ww := range watchMap {
- if strings.HasPrefix(ww.path, old) {
- ww.path = filepath.Join(fullname, strings.TrimPrefix(ww.path, old))
- }
- }
- }
- w.mu.Unlock()
-
- if watch.names[watch.rename] != 0 {
- watch.names[name] |= watch.names[watch.rename]
- delete(watch.names, watch.rename)
- mask = sysFSMOVESELF
- }
- }
-
- sendNameEvent := func() {
- w.sendEvent(fullname, watch.names[name]&mask)
- }
- if raw.Action != windows.FILE_ACTION_RENAMED_NEW_NAME {
- sendNameEvent()
- }
- if raw.Action == windows.FILE_ACTION_REMOVED {
- w.sendEvent(fullname, watch.names[name]&sysFSIGNORED)
- delete(watch.names, name)
- }
-
- w.sendEvent(fullname, watch.mask&w.toFSnotifyFlags(raw.Action))
- if raw.Action == windows.FILE_ACTION_RENAMED_NEW_NAME {
- fullname = filepath.Join(watch.path, watch.rename)
- sendNameEvent()
- }
-
- // Move to the next event in the buffer
- if raw.NextEntryOffset == 0 {
- break
- }
- offset += raw.NextEntryOffset
-
- // Error!
- if offset >= n {
- //lint:ignore ST1005 Windows should be capitalized
- w.sendError(errors.New(
- "Windows system assumed buffer larger than it is, events have likely been missed"))
- break
- }
- }
-
- if err := w.startRead(watch); err != nil {
- w.sendError(err)
- }
- }
-}
-
-func (w *Watcher) toWindowsFlags(mask uint64) uint32 {
- var m uint32
- if mask&sysFSMODIFY != 0 {
- m |= windows.FILE_NOTIFY_CHANGE_LAST_WRITE
- }
- if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 {
- m |= windows.FILE_NOTIFY_CHANGE_FILE_NAME | windows.FILE_NOTIFY_CHANGE_DIR_NAME
- }
- return m
-}
-
-func (w *Watcher) toFSnotifyFlags(action uint32) uint64 {
- switch action {
- case windows.FILE_ACTION_ADDED:
- return sysFSCREATE
- case windows.FILE_ACTION_REMOVED:
- return sysFSDELETE
- case windows.FILE_ACTION_MODIFIED:
- return sysFSMODIFY
- case windows.FILE_ACTION_RENAMED_OLD_NAME:
- return sysFSMOVEDFROM
- case windows.FILE_ACTION_RENAMED_NEW_NAME:
- return sysFSMOVEDTO
- }
- return 0
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
deleted file mode 100644
index 24c99cc49..000000000
--- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Package fsnotify provides a cross-platform interface for file system
-// notifications.
-//
-// Currently supported systems:
-//
-// Linux 2.6.32+ via inotify
-// BSD, macOS via kqueue
-// Windows via ReadDirectoryChangesW
-// illumos via FEN
-package fsnotify
-
-import (
- "errors"
- "fmt"
- "path/filepath"
- "strings"
-)
-
-// Event represents a file system notification.
-type Event struct {
- // 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".
- Name string
-
- // 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 ==.
- Op Op
-}
-
-// Op describes a set of file operations.
-type Op uint32
-
-// The operations fsnotify can trigger; see the documentation on [Watcher] for a
-// full description, and check them with [Event.Has].
-const (
- // A new pathname was created.
- Create Op = 1 << iota
-
- // The pathname was written to; this does *not* mean the write has finished,
- // and a write can be followed by more writes.
- Write
-
- // 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).
- Remove
-
- // The path was renamed to something else; any watched on it will be
- // removed.
- Rename
-
- // 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.
- Chmod
-)
-
-// Common errors that can be reported.
-var (
- ErrNonExistentWatch = errors.New("fsnotify: can't remove non-existent watch")
- ErrEventOverflow = errors.New("fsnotify: queue or buffer overflow")
- ErrClosed = errors.New("fsnotify: watcher already closed")
-)
-
-func (o Op) String() string {
- var b strings.Builder
- if o.Has(Create) {
- b.WriteString("|CREATE")
- }
- if o.Has(Remove) {
- b.WriteString("|REMOVE")
- }
- if o.Has(Write) {
- b.WriteString("|WRITE")
- }
- if o.Has(Rename) {
- b.WriteString("|RENAME")
- }
- if o.Has(Chmod) {
- b.WriteString("|CHMOD")
- }
- if b.Len() == 0 {
- return "[no events]"
- }
- return b.String()[1:]
-}
-
-// Has reports if this operation has the given operation.
-func (o Op) Has(h Op) bool { return o&h != 0 }
-
-// Has reports if this event has the given operation.
-func (e Event) Has(op Op) bool { return e.Op.Has(op) }
-
-// String returns a string representation of the event with their path.
-func (e Event) String() string {
- return fmt.Sprintf("%-13s %q", e.Op.String(), e.Name)
-}
-
-type (
- addOpt func(opt *withOpts)
- withOpts struct {
- bufsize int
- }
-)
-
-var defaultOpts = withOpts{
- bufsize: 65536, // 64K
-}
-
-func getOptions(opts ...addOpt) withOpts {
- with := defaultOpts
- for _, o := range opts {
- o(&with)
- }
- return with
-}
-
-// WithBufferSize sets the [ReadDirectoryChangesW] buffer size.
-//
-// This only has effect on Windows systems, and is a no-op for other backends.
-//
-// The default value is 64K (65536 bytes) which is the highest value that works
-// on all filesystems and should be enough for most applications, but if you
-// have a large burst of events it may not be enough. You can increase it if
-// you're hitting "queue or buffer overflow" errors ([ErrEventOverflow]).
-//
-// [ReadDirectoryChangesW]: https://learn.microsoft.com/en-gb/windows/win32/api/winbase/nf-winbase-readdirectorychangesw
-func WithBufferSize(bytes int) addOpt {
- return func(opt *withOpts) { opt.bufsize = bytes }
-}
-
-// Check if this path is recursive (ends with "/..." or "\..."), and return the
-// path with the /... stripped.
-func recursivePath(path string) (string, bool) {
- if filepath.Base(path) == "..." {
- return filepath.Dir(path), true
- }
- return path, false
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh
deleted file mode 100644
index 99012ae65..000000000
--- a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/usr/bin/env zsh
-[ "${ZSH_VERSION:-}" = "" ] && echo >&2 "Only works with zsh" && exit 1
-setopt err_exit no_unset pipefail extended_glob
-
-# Simple script to update the godoc comments on all watchers so you don't need
-# to update the same comment 5 times.
-
-watcher=$(<<EOF
-// 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).
-//
-// # Linux notes
-//
-// When a file is removed a Remove event won't be emitted until all file
-// descriptors are closed, and deletes will always emit a Chmod. For example:
-//
-// fp := os.Open("file")
-// os.Remove("file") // Triggers Chmod
-// fp.Close() // Triggers 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 the /proc file:
-//
-// # 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 notes (macOS, BSD)
-//
-// 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, as well as /etc/login.conf on BSD
-// systems.
-//
-// # Windows notes
-//
-// Paths can be added as "C:\\path\\to\\dir", but forward slashes
-// ("C:/path/to/dir") will also work.
-//
-// When a watched directory is removed it will always send an event for the
-// directory itself, but may not send events for all files in that directory.
-// Sometimes it will send events for all times, sometimes it will send no
-// events, and often only for some files.
-//
-// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest
-// value that is guaranteed to work with SMB filesystems. If you have many
-// events in quick succession this may not be enough, and you will have to use
-// [WithBufferSize] to increase the value.
-EOF
-)
-
-new=$(<<EOF
-// NewWatcher creates a new Watcher.
-EOF
-)
-
-newbuffered=$(<<EOF
-// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events
-// channel.
-//
-// The main use case for this is situations with a very large number of events
-// where the kernel buffer size can't be increased (e.g. due to lack of
-// permissions). An unbuffered Watcher will perform better for almost all use
-// cases, and whenever possible you will be better off increasing the kernel
-// buffers instead of adding a large userspace buffer.
-EOF
-)
-
-add=$(<<EOF
-// Add starts monitoring the path for changes.
-//
-// A path can only be watched once; watching it more than once is a no-op and will
-// not return an error. Paths that do not yet exist on the filesystem cannot be
-// watched.
-//
-// A watch will be automatically removed if the watched path is deleted or
-// renamed. The exception is the Windows backend, which doesn't remove the
-// watcher on renames.
-//
-// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special
-// filesystems (/proc, /sys, etc.) generally don't work.
-//
-// Returns [ErrClosed] if [Watcher.Close] was called.
-//
-// See [Watcher.AddWith] for a version that allows adding options.
-//
-// # Watching directories
-//
-// All files in a directory are monitored, including new files that are created
-// after the watcher is started. Subdirectories are not watched (i.e. it's
-// non-recursive).
-//
-// # Watching files
-//
-// Watching individual files (rather than directories) is generally not
-// recommended as many programs (especially editors) update files atomically: it
-// will write to a temporary file which is then moved to to destination,
-// overwriting the original (or some variant thereof). The watcher on the
-// original file is now lost, as that no longer exists.
-//
-// The upshot of this is that a power failure or crash won't leave a
-// half-written file.
-//
-// Watch the parent directory and use Event.Name to filter out files you're not
-// interested in. There is an example of this in cmd/fsnotify/file.go.
-EOF
-)
-
-addwith=$(<<EOF
-// AddWith is like [Watcher.Add], but allows adding options. When using Add()
-// the defaults described below are used.
-//
-// Possible options are:
-//
-// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on
-// other platforms. The default is 64K (65536 bytes).
-EOF
-)
-
-remove=$(<<EOF
-// Remove stops monitoring the path for changes.
-//
-// Directories are always removed non-recursively. For example, if you added
-// /tmp/dir and /tmp/dir/subdir then you will need to remove both.
-//
-// Removing a path that has not yet been added returns [ErrNonExistentWatch].
-//
-// Returns nil if [Watcher.Close] was called.
-EOF
-)
-
-close=$(<<EOF
-// Close removes all watches and closes the Events channel.
-EOF
-)
-
-watchlist=$(<<EOF
-// WatchList returns all paths explicitly added with [Watcher.Add] (and are not
-// yet removed).
-//
-// Returns nil if [Watcher.Close] was called.
-EOF
-)
-
-events=$(<<EOF
- // Events 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. For example when compiling a large Go program
- // you may get hundreds of Write events, and you may
- // want to wait until you've stopped receiving them
- // (see the dedup example in cmd/fsnotify).
- //
- // 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.
-EOF
-)
-
-errors=$(<<EOF
- // Errors sends any errors.
- //
- // ErrEventOverflow is used to indicate there are too many events:
- //
- // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl)
- // - windows: The buffer size is too small; WithBufferSize() can be used to increase it.
- // - kqueue, fen: Not used.
-EOF
-)
-
-set-cmt() {
- local pat=$1
- local cmt=$2
-
- IFS=$'\n' local files=($(grep -n $pat backend_*~*_test.go))
- for f in $files; do
- IFS=':' local fields=($=f)
- local file=$fields[1]
- local end=$(( $fields[2] - 1 ))
-
- # Find start of comment.
- local start=0
- IFS=$'\n' local lines=($(head -n$end $file))
- for (( i = 1; i <= $#lines; i++ )); do
- local line=$lines[-$i]
- if ! grep -q '^[[:space:]]*//' <<<$line; then
- start=$(( end - (i - 2) ))
- break
- fi
- done
-
- head -n $(( start - 1 )) $file >/tmp/x
- print -r -- $cmt >>/tmp/x
- tail -n+$(( end + 1 )) $file >>/tmp/x
- mv /tmp/x $file
- done
-}
-
-set-cmt '^type Watcher struct ' $watcher
-set-cmt '^func NewWatcher(' $new
-set-cmt '^func NewBufferedWatcher(' $newbuffered
-set-cmt '^func (w \*Watcher) Add(' $add
-set-cmt '^func (w \*Watcher) AddWith(' $addwith
-set-cmt '^func (w \*Watcher) Remove(' $remove
-set-cmt '^func (w \*Watcher) Close(' $close
-set-cmt '^func (w \*Watcher) WatchList(' $watchlist
-set-cmt '^[[:space:]]*Events *chan Event$' $events
-set-cmt '^[[:space:]]*Errors *chan error$' $errors
diff --git a/vendor/github.com/fsnotify/fsnotify/system_bsd.go b/vendor/github.com/fsnotify/fsnotify/system_bsd.go
deleted file mode 100644
index 4322b0b88..000000000
--- a/vendor/github.com/fsnotify/fsnotify/system_bsd.go
+++ /dev/null
@@ -1,8 +0,0 @@
-//go:build freebsd || openbsd || netbsd || dragonfly
-// +build freebsd openbsd netbsd dragonfly
-
-package fsnotify
-
-import "golang.org/x/sys/unix"
-
-const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC
diff --git a/vendor/github.com/fsnotify/fsnotify/system_darwin.go b/vendor/github.com/fsnotify/fsnotify/system_darwin.go
deleted file mode 100644
index 5da5ffa78..000000000
--- a/vendor/github.com/fsnotify/fsnotify/system_darwin.go
+++ /dev/null
@@ -1,9 +0,0 @@
-//go:build darwin
-// +build darwin
-
-package fsnotify
-
-import "golang.org/x/sys/unix"
-
-// note: this constant is not defined on BSD
-const openMode = unix.O_EVTONLY | unix.O_CLOEXEC