From 5a6a11ddad23e24ffaf2eabaef60f07c20138992 Mon Sep 17 00:00:00 2001 From: Robin Jarry Date: Thu, 9 Mar 2023 22:26:03 +0100 Subject: fswatcher: fix bsd support Fix the following error when running maildir on freebsd: could not create file system watcher: Unsupported OS: freebsd Do not register based on os type. Register based on supported API. Rename linux -> inotify and darwin -> fsevents. Only build fsevents on darwin, and inotify on all other platforms. Fixes: a0935a3de0ce ("worker/lib: implement an fswatcher interface") Reported-by: Jens Grassel Signed-off-by: Robin Jarry --- worker/handlers/register.go | 12 +++--- worker/lib/watchers/darwin/darwin.go | 84 ------------------------------------ worker/lib/watchers/fsevents.go | 84 ++++++++++++++++++++++++++++++++++++ worker/lib/watchers/inotify.go | 76 ++++++++++++++++++++++++++++++++ worker/lib/watchers/linux/linux.go | 73 ------------------------------- worker/watcher_darwin.go | 6 --- worker/watcher_enabled.go | 3 -- worker/worker_enabled.go | 2 +- 8 files changed, 167 insertions(+), 173 deletions(-) delete mode 100644 worker/lib/watchers/darwin/darwin.go create mode 100644 worker/lib/watchers/fsevents.go create mode 100644 worker/lib/watchers/inotify.go delete mode 100644 worker/lib/watchers/linux/linux.go delete mode 100644 worker/watcher_darwin.go delete mode 100644 worker/watcher_enabled.go diff --git a/worker/handlers/register.go b/worker/handlers/register.go index c94a256e..4123665f 100644 --- a/worker/handlers/register.go +++ b/worker/handlers/register.go @@ -29,15 +29,15 @@ func GetHandlerForScheme(scheme string, worker *types.Worker) (types.Backend, er type WatcherFactoryFunc func() (types.FSWatcher, error) -var watcherFactories map[string]WatcherFactoryFunc = make(map[string]WatcherFactoryFunc) +var watcherFactory WatcherFactoryFunc -func RegisterWatcherFactory(os string, fn WatcherFactoryFunc) { - watcherFactories[os] = fn +func RegisterWatcherFactory(fn WatcherFactoryFunc) { + watcherFactory = fn } func NewWatcher() (types.FSWatcher, error) { - if fn, ok := watcherFactories[runtime.GOOS]; ok { - return fn() + if watcherFactory == nil { + return nil, fmt.Errorf("Unsupported OS: %s", runtime.GOOS) } - return nil, fmt.Errorf("Unsupported OS: %s", runtime.GOOS) + return watcherFactory() } diff --git a/worker/lib/watchers/darwin/darwin.go b/worker/lib/watchers/darwin/darwin.go deleted file mode 100644 index e20761f3..00000000 --- a/worker/lib/watchers/darwin/darwin.go +++ /dev/null @@ -1,84 +0,0 @@ -//go:build darwin -// +build darwin - -package darwin - -import ( - "time" - - "git.sr.ht/~rjarry/aerc/log" - "git.sr.ht/~rjarry/aerc/worker/handlers" - "git.sr.ht/~rjarry/aerc/worker/types" - "github.com/fsnotify/fsevents" -) - -func init() { - handlers.RegisterWatcherFactory("darwin", newDarwinWatcher) -} - -type darwinWatcher struct { - ch chan *types.FSEvent - w *fsevents.EventStream - watcherCh chan []fsevents.Event -} - -func newDarwinWatcher() (types.FSWatcher, error) { - watcher := &darwinWatcher{ - watcherCh: make(chan []fsevents.Event), - ch: make(chan *types.FSEvent), - w: &fsevents.EventStream{ - Flags: fsevents.FileEvents | fsevents.WatchRoot, - Latency: 500 * time.Millisecond, - }, - } - return watcher, nil -} - -func (w *darwinWatcher) watch() { - defer log.PanicHandler() - for events := range w.w.Events { - for _, ev := range events { - switch { - case ev.Flags&fsevents.ItemCreated > 0: - w.ch <- &types.FSEvent{ - Operation: types.FSCreate, - Path: ev.Path, - } - case ev.Flags&fsevents.ItemRenamed > 0: - w.ch <- &types.FSEvent{ - Operation: types.FSRename, - Path: ev.Path, - } - case ev.Flags&fsevents.ItemRemoved > 0: - w.ch <- &types.FSEvent{ - Operation: types.FSRemove, - Path: ev.Path, - } - } - } - } -} - -func (w *darwinWatcher) Configure(root string) error { - dev, err := fsevents.DeviceForPath(root) - if err != nil { - return err - } - w.w.Device = dev - w.w.Paths = []string{root} - w.w.Start() - go w.watch() - return nil -} - -func (w *darwinWatcher) Events() chan *types.FSEvent { - return w.ch -} - -func (w *darwinWatcher) Add(p string) error { - return nil -} - -func (w *darwinWatcher) Remove(p string) error { - return nil -} diff --git a/worker/lib/watchers/fsevents.go b/worker/lib/watchers/fsevents.go new file mode 100644 index 00000000..7b657999 --- /dev/null +++ b/worker/lib/watchers/fsevents.go @@ -0,0 +1,84 @@ +//go:build darwin +// +build darwin + +package watchers + +import ( + "time" + + "git.sr.ht/~rjarry/aerc/log" + "git.sr.ht/~rjarry/aerc/worker/handlers" + "git.sr.ht/~rjarry/aerc/worker/types" + "github.com/fsnotify/fsevents" +) + +func init() { + handlers.RegisterWatcherFactory(newDarwinWatcher) +} + +type darwinWatcher struct { + ch chan *types.FSEvent + w *fsevents.EventStream + watcherCh chan []fsevents.Event +} + +func newDarwinWatcher() (types.FSWatcher, error) { + watcher := &darwinWatcher{ + watcherCh: make(chan []fsevents.Event), + ch: make(chan *types.FSEvent), + w: &fsevents.EventStream{ + Flags: fsevents.FileEvents | fsevents.WatchRoot, + Latency: 500 * time.Millisecond, + }, + } + return watcher, nil +} + +func (w *darwinWatcher) watch() { + defer log.PanicHandler() + for events := range w.w.Events { + for _, ev := range events { + switch { + case ev.Flags&fsevents.ItemCreated > 0: + w.ch <- &types.FSEvent{ + Operation: types.FSCreate, + Path: ev.Path, + } + case ev.Flags&fsevents.ItemRenamed > 0: + w.ch <- &types.FSEvent{ + Operation: types.FSRename, + Path: ev.Path, + } + case ev.Flags&fsevents.ItemRemoved > 0: + w.ch <- &types.FSEvent{ + Operation: types.FSRemove, + Path: ev.Path, + } + } + } + } +} + +func (w *darwinWatcher) Configure(root string) error { + dev, err := fsevents.DeviceForPath(root) + if err != nil { + return err + } + w.w.Device = dev + w.w.Paths = []string{root} + w.w.Start() + go w.watch() + return nil +} + +func (w *darwinWatcher) Events() chan *types.FSEvent { + return w.ch +} + +func (w *darwinWatcher) Add(p string) error { + return nil +} + +func (w *darwinWatcher) Remove(p string) error { + return nil +} diff --git a/worker/lib/watchers/inotify.go b/worker/lib/watchers/inotify.go new file mode 100644 index 00000000..027ef4f2 --- /dev/null +++ b/worker/lib/watchers/inotify.go @@ -0,0 +1,76 @@ +//go:build !darwin +// +build !darwin + +package watchers + +import ( + "git.sr.ht/~rjarry/aerc/log" + "git.sr.ht/~rjarry/aerc/worker/handlers" + "git.sr.ht/~rjarry/aerc/worker/types" + "github.com/fsnotify/fsnotify" +) + +func init() { + handlers.RegisterWatcherFactory(newInotifyWatcher) +} + +type inotifyWatcher struct { + w *fsnotify.Watcher + ch chan *types.FSEvent +} + +func newInotifyWatcher() (types.FSWatcher, error) { + watcher := &inotifyWatcher{ + ch: make(chan *types.FSEvent), + } + w, err := fsnotify.NewWatcher() + if err != nil { + return nil, err + } + watcher.w = w + + go watcher.watch() + return watcher, nil +} + +func (w *inotifyWatcher) watch() { + defer log.PanicHandler() + for ev := range w.w.Events { + // we only care about files being created, removed or renamed + switch ev.Op { + case fsnotify.Create: + w.ch <- &types.FSEvent{ + Operation: types.FSCreate, + Path: ev.Name, + } + case fsnotify.Remove: + w.ch <- &types.FSEvent{ + Operation: types.FSRemove, + Path: ev.Name, + } + case fsnotify.Rename: + w.ch <- &types.FSEvent{ + Operation: types.FSRename, + Path: ev.Name, + } + default: + continue + } + } +} + +func (w *inotifyWatcher) Configure(root string) error { + return w.w.Add(root) +} + +func (w *inotifyWatcher) Events() chan *types.FSEvent { + return w.ch +} + +func (w *inotifyWatcher) Add(p string) error { + return w.w.Add(p) +} + +func (w *inotifyWatcher) Remove(p string) error { + return w.w.Remove(p) +} diff --git a/worker/lib/watchers/linux/linux.go b/worker/lib/watchers/linux/linux.go deleted file mode 100644 index 473bb05e..00000000 --- a/worker/lib/watchers/linux/linux.go +++ /dev/null @@ -1,73 +0,0 @@ -package linux - -import ( - "git.sr.ht/~rjarry/aerc/log" - "git.sr.ht/~rjarry/aerc/worker/handlers" - "git.sr.ht/~rjarry/aerc/worker/types" - "github.com/fsnotify/fsnotify" -) - -func init() { - handlers.RegisterWatcherFactory("linux", newInotifyWatcher) -} - -type inotifyWatcher struct { - w *fsnotify.Watcher - ch chan *types.FSEvent -} - -func newInotifyWatcher() (types.FSWatcher, error) { - watcher := &inotifyWatcher{ - ch: make(chan *types.FSEvent), - } - w, err := fsnotify.NewWatcher() - if err != nil { - return nil, err - } - watcher.w = w - - go watcher.watch() - return watcher, nil -} - -func (w *inotifyWatcher) watch() { - defer log.PanicHandler() - for ev := range w.w.Events { - // we only care about files being created, removed or renamed - switch ev.Op { - case fsnotify.Create: - w.ch <- &types.FSEvent{ - Operation: types.FSCreate, - Path: ev.Name, - } - case fsnotify.Remove: - w.ch <- &types.FSEvent{ - Operation: types.FSRemove, - Path: ev.Name, - } - case fsnotify.Rename: - w.ch <- &types.FSEvent{ - Operation: types.FSRename, - Path: ev.Name, - } - default: - continue - } - } -} - -func (w *inotifyWatcher) Configure(root string) error { - return w.w.Add(root) -} - -func (w *inotifyWatcher) Events() chan *types.FSEvent { - return w.ch -} - -func (w *inotifyWatcher) Add(p string) error { - return w.w.Add(p) -} - -func (w *inotifyWatcher) Remove(p string) error { - return w.w.Remove(p) -} diff --git a/worker/watcher_darwin.go b/worker/watcher_darwin.go deleted file mode 100644 index fa1af712..00000000 --- a/worker/watcher_darwin.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build darwin -// +build darwin - -package worker - -import _ "git.sr.ht/~rjarry/aerc/worker/lib/watchers/darwin" diff --git a/worker/watcher_enabled.go b/worker/watcher_enabled.go deleted file mode 100644 index 16333f43..00000000 --- a/worker/watcher_enabled.go +++ /dev/null @@ -1,3 +0,0 @@ -package worker - -import _ "git.sr.ht/~rjarry/aerc/worker/lib/watchers/linux" diff --git a/worker/worker_enabled.go b/worker/worker_enabled.go index a644525f..697ca402 100644 --- a/worker/worker_enabled.go +++ b/worker/worker_enabled.go @@ -3,7 +3,7 @@ package worker // the following workers are always enabled import ( _ "git.sr.ht/~rjarry/aerc/worker/imap" + _ "git.sr.ht/~rjarry/aerc/worker/lib/watchers" _ "git.sr.ht/~rjarry/aerc/worker/maildir" - _ "git.sr.ht/~rjarry/aerc/worker/mbox" ) -- cgit v1.2.3-54-g00ecf