func New(dev Device, since EventID, interval time.Duration, flags CreateFlags, paths ...string) *Stream { cpaths := C.fswatch_make_mutable_array() defer C.free(unsafe.Pointer(cpaths)) for _, dir := range paths { path := C.CString(dir) defer C.free(unsafe.Pointer(path)) str := C.CFStringCreateWithCString(nil, path, C.kCFStringEncodingUTF8) defer C.free(unsafe.Pointer(str)) C.CFArrayAppendValue(cpaths, unsafe.Pointer(str)) } csince := C.FSEventStreamEventId(since) cinterval := C.CFTimeInterval(interval / time.Second) cflags := C.FSEventStreamCreateFlags(flags &^ CF_USECFTYPES) s := new(Stream) s.Chan = make(chan []Event) ctx := C.FSEventStreamContext{info: unsafe.Pointer(&s.Chan)} var cstream C.FSEventStreamRef if dev == 0 { cstream = C.fswatch_create(&ctx, cpaths, csince, cinterval, cflags) } else { cdev := C.dev_t(dev) cstream = C.fswatch_create_relative_to_device( cdev, &ctx, cpaths, csince, cinterval, cflags) } s.cstream = cstream return s }
func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]string) { st, ok := fi.Sys().(*syscall.Stat_t) if !ok { return } h.Uid = int(st.Uid) h.Gid = int(st.Gid) if st.Mode&syscall.S_IFMT == syscall.S_IFBLK || st.Mode&syscall.S_IFMT == syscall.S_IFCHR { h.Devminor = int64(C.my_minor(C.dev_t(st.Rdev))) h.Devmajor = int64(C.my_major(C.dev_t(st.Rdev))) } // If we have already seen this inode, generate a hardlink p, ok := seen[uint64(st.Ino)] if ok { h.Linkname = p h.Typeflag = tar.TypeLink } else { seen[uint64(st.Ino)] = h.Name } }
// Start listening to an event stream. func (es *EventStream) Start() { cPaths := C.ArrayCreateMutable(C.int(len(es.Paths))) defer C.CFRelease(C.CFTypeRef(cPaths)) for _, p := range es.Paths { p, _ = filepath.Abs(p) cpath := C.CString(p) defer C.free(unsafe.Pointer(cpath)) str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8) C.CFArrayAppendValue(cPaths, unsafe.Pointer(str)) } since := C.FSEventStreamEventId(EventIDSinceNow) if es.Resume { since = C.FSEventStreamEventId(es.EventID) } if es.Events == nil { es.Events = make(chan []Event) } es.registryID = registry.Add(es) context := C.FSEventStreamContext{} info := C.uintptr_t(es.registryID) latency := C.CFTimeInterval(float64(es.Latency) / float64(time.Second)) if es.Device != 0 { es.stream = C.EventStreamCreateRelativeToDevice(&context, info, C.dev_t(es.Device), cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags)) } else { es.stream = C.EventStreamCreate(&context, info, cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags)) } started := make(chan struct{}) go func() { runtime.LockOSThread() es.rlref = C.CFRunLoopGetCurrent() C.FSEventStreamScheduleWithRunLoop(es.stream, es.rlref, C.kCFRunLoopDefaultMode) C.FSEventStreamStart(es.stream) close(started) C.CFRunLoopRun() }() if !es.hasFinalizer { runtime.SetFinalizer(es, finalizer) es.hasFinalizer = true } <-started }
func DeviceFromDevNum(u Udev, t DeviceType, num DevNum) Device { return Device{C.udev_device_new_from_devnum(u.ptr, C.char(t), C.dev_t(num))} }
// EventIDForDeviceBeforeTime returns an event ID before a given time. func EventIDForDeviceBeforeTime(dev int32, before time.Time) uint64 { tm := C.CFAbsoluteTime(before.Unix()) return uint64(C.FSEventsGetLastEventIdForDeviceBeforeTime(C.dev_t(dev), tm)) }
// https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/Reference/reference.html#jumpTo_5 func LastEventBefore(dev Device, ts time.Time) EventID { return EventID( C.FSEventsGetLastEventIdForDeviceBeforeTime( C.dev_t(dev), C.CFAbsoluteTime(ts.Unix()))) }
func Minor(rdev uint64) uint { minor := C.my_minor(C.dev_t(rdev)) return uint(minor) }
func Major(rdev uint64) uint { major := C.my_major(C.dev_t(rdev)) return uint(major) }