blob: 442e898879e91c25fa5db7a7fa6b87adb2b1703b [file] [log] [blame]
// +build darwin freebsd linux netbsd openbsd windows
package follow
import (
"github.com/howeyc/fsnotify"
)
// newFSNotifyWatch returns a function that listens on fsnotify and sends
// corresponding modification events.
// For each fsnotify modification event, a single nil value is sent on the
// events channel. Further fsnotify events are not received until the nil
// value is received from the events channel.
// The function sends any errors on the events channel.
func newFSNotifyWatch(filename string) func(chan<- error, <-chan bool, chan<- bool) {
return func(events chan<- error, stop <-chan bool, done chan<- bool) {
defer close(done)
defer close(events)
source, err := fsnotify.NewWatcher()
if err != nil {
events <- err
return
}
defer source.Close()
if err := source.Watch(filename); err != nil {
events <- err
return
}
for {
// Receive:
// (A) An fsnotify modification event. Send nil.
// (B) An fsnotify error. Send the error.
// (C) A stop command. Stop listening and clean up.
select {
case event := <-source.Event:
if event.IsModify() {
if sendEvent(events, nil, stop) {
return
}
}
case err := <-source.Error:
if sendEvent(events, err, stop) {
return
}
case <-stop:
return
}
// As select does not prioritize cases, it could starve
// the stop case. Look for a stop command again.
select {
case <-stop:
return
default:
}
}
}
}