// Must run within the I/O thread. func (w *Watcher) startRead(watch *watch) error { if e := syscall.CancelIo(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CancelIo", e) w.deleteWatch(watch) } mask := toWindowsFlags(watch.mask) for _, m := range watch.names { mask |= toWindowsFlags(m) } if mask == 0 { if e := syscall.CloseHandle(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CloseHandle", e) } delete(w.watches[watch.ino.volume], watch.ino.index) return nil } e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) if e != nil { err := os.NewSyscallError("ReadDirectoryChanges", e) if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { // Watched directory was probably removed if w.sendEvent(watch.path, watch.mask&FS_DELETE_SELF) { if watch.mask&FS_ONESHOT != 0 { watch.mask = 0 } } err = nil } w.deleteWatch(watch) w.startRead(watch) return err } return nil }
// readDirChanges tells the system to store file change information in grip's // buffer. Directory changes that occur between calls to this function are added // to the buffer and then, returned with the next call. func (g *grip) readDirChanges() error { return syscall.ReadDirectoryChanges( g.handle, &g.buffer[0], uint32(unsafe.Sizeof(g.buffer)), g.recursive, encode(g.filter), nil, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped)), 0, ) }