kqueue: don't immediately remove watches for all files in a directory on Delete event (#526)
The problem was that that on Delete events for directories it would call
Watcher.Remove() for all files in that directory too. This is fine if you call
w.Remove() from the application, but if you rm -rf a directory the directory
itself tends to be the first remove event (on FreeBSD at least):
So what would happen is that the internal state for /tmp/xxx/a etc. would get
removed, and when the event gets processed we no longer have access to it.
Move Remove() to remove() with a flag to control removing files. If a watched
directory is removed then the files will emit their own delete event, so we
don't really need to do this.
Fixes #514
Also:
- Don't send Remove|Write events; that's never really useful: if it's
gone, then it's gone. No other backends do this.
- Save a stat call by checking the readdir error instead.
- Don't stat every directory; this isn't really needed, and getting a
write event before a delete is fine (and this didn't suppress the
write even anyway).
- Add test/kqueue.c; just a simple implementation to test things.