if len(ts) != 2 {
return EINVAL
}
- err := utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+ // Darwin setattrlist can set nanosecond timestamps
+ err := setattrlistTimes(path, ts)
+ if err != ENOSYS {
+ return err
+ }
+ err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS {
return err
}
const (
attrBitMapCount = 5
+ attrCmnModtime = 0x00000400
+ attrCmnAcctime = 0x00001000
attrCmnFullpath = 0x08000000
)
return
}
+func setattrlistTimes(path string, times []Timespec) error {
+ _p0, err := BytePtrFromString(path)
+ if err != nil {
+ return err
+ }
+
+ var attrList attrList
+ attrList.bitmapCount = attrBitMapCount
+ attrList.CommonAttr = attrCmnModtime | attrCmnAcctime
+
+ // order is mtime, atime: the opposite of Chtimes
+ attributes := [2]Timespec{times[1], times[0]}
+ const options = 0
+ _, _, e1 := Syscall6(
+ SYS_SETATTRLIST,
+ uintptr(unsafe.Pointer(_p0)),
+ uintptr(unsafe.Pointer(&attrList)),
+ uintptr(unsafe.Pointer(&attributes)),
+ uintptr(unsafe.Sizeof(attributes)),
+ uintptr(options),
+ 0,
+ )
+ if e1 != 0 {
+ return e1
+ }
+ return nil
+}
+
func utimensat(dirfd int, path string, times *[2]Timespec, flag int) error {
// Darwin doesn't support SYS_UTIMENSAT
return ENOSYS