From 0cf23b50244e23a85277350a5393d116f2c4c06f Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 3 Nov 2015 19:09:03 -0500 Subject: fold inotify/inutil into inotify --- inotify/channels.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 inotify/channels.go (limited to 'inotify/channels.go') diff --git a/inotify/channels.go b/inotify/channels.go new file mode 100644 index 0000000..737b312 --- /dev/null +++ b/inotify/channels.go @@ -0,0 +1,96 @@ +// Copyright 2015 Luke Shumaker . +// +// This is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of +// the License, or (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this manual; if not, see +// . + +package inotify + +import ( + "os" + "syscall" +) + +// A Watcher is a wrapper around an (*Inotify) that exposes a +// channel-based interface that is much nicer to work with. +type Watcher struct { + Events <-chan Event + Errors <-chan error + events chan<- Event + errors chan<- error + in *Inotify +} + +// Wraps InotifyInit() +func WatcherInit() (*Watcher, error) { + in, err := InotifyInit() + return newWatcher(in, err) +} + +// Wraps InotifyInit1() +func WatcherInit1(flags int) (*Watcher, error) { + in, err := InotifyInit1(flags &^ IN_NONBLOCK) + return newWatcher(in, err) +} + +func newWatcher(in *Inotify, err error) (*Watcher, error) { + events := make(chan Event) + errors := make(chan error) + o := &Watcher{ + Events: events, + events: events, + Errors: errors, + errors: errors, + in: in, + } + go o.worker() + return o, err +} + +// Wraps Inotify.AddWatch(); adds or modifies a watch. +func (o *Watcher) AddWatch(path string, mask Mask) (Wd, error) { + return o.in.AddWatch(path, mask) +} + +// Wraps Inotify.RmWatch(); removes a watch. +func (o *Watcher) RmWatch(wd Wd) error { + return o.in.RmWatch(wd) +} + +// Wraps Inotify.Close(). Unlike Inotify.Close(), +// this cannot block. Also unlike Inotify.Close(), nothing +// may be received from the channel after this is called. +func (o *Watcher) Close() { + func() { + defer recover() + close(o.events) + close(o.errors) + }() + go o.in.Close() +} + +func (o *Watcher) worker() { + defer recover() + for { + ev, err := o.in.Read() + if ev.Wd >= 0 { + o.events <- ev + } + if err != nil { + if err.(*os.SyscallError).Err == syscall.EBADF { + o.Close() + } + o.errors <- err + } + } +} -- cgit v1.2.3