//export gostream func gostream(_, ctx unsafe.Pointer, n C.size_t, paths, flags, ids uintptr) { const ( offchar = unsafe.Sizeof((*C.char)(nil)) offflag = unsafe.Sizeof(C.FSEventStreamEventFlags(0)) offid = unsafe.Sizeof(C.FSEventStreamEventId(0)) ) if n == 0 { return } ev := make([]FSEvent, 0, int(n)) for i := uintptr(0); i < uintptr(n); i++ { switch flags := *(*uint32)(unsafe.Pointer((flags + i*offflag))); { case flags&uint32(FSEventsEventIdsWrapped) != 0: atomic.StoreUint64(&since, uint64(C.FSEventsGetCurrentEventId())) default: ev = append(ev, FSEvent{ Path: C.GoString(*(**C.char)(unsafe.Pointer(paths + i*offchar))), Flags: flags, ID: *(*uint64)(unsafe.Pointer(ids + i*offid)), }) } } (*(*streamFunc)(ctx))(ev) }
// LatestEventID returns the most recently generated event ID, system-wide. func LatestEventID() uint64 { return uint64(C.FSEventsGetCurrentEventId()) }
import ( "errors" "os" "sync" "sync/atomic" "time" "unsafe" ) var nilstream C.FSEventStreamRef // Default arguments for FSEventStreamCreate function. var ( latency C.CFTimeInterval flags = C.FSEventStreamCreateFlags(C.kFSEventStreamCreateFlagFileEvents | C.kFSEventStreamCreateFlagNoDefer) since = uint64(C.FSEventsGetCurrentEventId()) ) var runloop C.CFRunLoopRef // global runloop which all streams are registered with var wg sync.WaitGroup // used to wait until the runloop starts // source is used for synchronization purposes - it signals when runloop has // started and is ready via the wg. It also serves purpose of a dummy source, // thanks to it the runloop does not return as it also has at least one source // registered. var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{ perform: (C.CFRunLoopPerformCallBack)(C.gosource), }) // Errors returned when FSEvents functions fail. var (
// https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/Reference/reference.html#jumpTo_4 func Current() EventID { return EventID(C.FSEventsGetCurrentEventId()) }