Watch the *directory* for file deletions instead of the file itself.

inotify works on the inode, not the path.  Deleting the file doesn't
touch the inode, so doesn't generate an event on the file.

Fixes #57
This commit is contained in:
David Sansome 2015-09-29 18:04:25 +10:00
parent 760f3e6edc
commit e681532458
1 changed files with 12 additions and 2 deletions

View File

@ -59,15 +59,22 @@ func (fw *InotifyFileWatcher) BlockUntilExists(t *tomb.Tomb) error {
func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, fi os.FileInfo) *FileChanges { func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, fi os.FileInfo) *FileChanges {
changes := NewFileChanges() changes := NewFileChanges()
err := fw.w.Watch(fw.Filename) if err := fw.w.Watch(fw.Filename); err != nil {
if err != nil {
util.Fatal("Error watching %v: %v", fw.Filename, err) util.Fatal("Error watching %v: %v", fw.Filename, err)
} }
// Watch the directory to be notified when the file is deleted since the file
// watch is on the inode, not the path.
dirname := filepath.Dir(fw.Filename)
if err := fw.w.WatchFlags(dirname, fsnotify.FSN_DELETE); err != nil {
util.Fatal("Error watching %v: %v", dirname, err)
}
fw.Size = fi.Size() fw.Size = fi.Size()
go func() { go func() {
defer fw.w.RemoveWatch(fw.Filename) defer fw.w.RemoveWatch(fw.Filename)
defer fw.w.RemoveWatch(dirname)
defer changes.Close() defer changes.Close()
for { for {
@ -87,6 +94,9 @@ func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, fi os.FileInfo) *FileCh
switch { switch {
case evt.IsDelete(): case evt.IsDelete():
if filepath.Base(evt.Name) != filepath.Base(fw.Filename) {
continue
}
fallthrough fallthrough
case evt.IsRename(): case evt.IsRename():