Browse Source

unix: use setattrlist for UtimesNanoAt on Darwin

Use to setarrlist to implement UtimesNanoAt with nanosecond precision
(on Mac OS 10.13 with APFS). Translate AT_SYMLINK_NOFOLLOW to
FSOPT_NOFOLLOW correspondingly.

Change-Id: I1468a1f4eecb53b2280ff6329b1ec64e204701f1
Reviewed-on: https://go-review.googlesource.com/75650
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Tobias Klauser 8 years ago
parent
commit
46eaec7899

+ 1 - 0
unix/mkerrors.sh

@@ -426,6 +426,7 @@ ccflags="$@"
 		$2 ~ /^UTIME_/ ||
 		$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
 		$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
+		$2 ~ /^FSOPT_/ ||
 		$2 ~ /^WDIOC_/ ||
 		$2 !~ "WMESGLEN" &&
 		$2 ~ /^W[A-Z0-9]+$/ ||

+ 5 - 1
unix/syscall_bsd.go

@@ -571,7 +571,7 @@ func UtimesNano(path string, ts []Timespec) error {
 		return EINVAL
 	}
 	// Darwin setattrlist can set nanosecond timestamps
-	err := setattrlistTimes(path, ts)
+	err := setattrlistTimes(path, ts, 0)
 	if err != ENOSYS {
 		return err
 	}
@@ -595,6 +595,10 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
 	if len(ts) != 2 {
 		return EINVAL
 	}
+	err := setattrlistTimes(path, ts, flags)
+	if err != ENOSYS {
+		return err
+	}
 	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
 }
 

+ 5 - 3
unix/syscall_darwin.go

@@ -187,7 +187,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	return
 }
 
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
 	_p0, err := BytePtrFromString(path)
 	if err != nil {
 		return err
@@ -199,8 +199,10 @@ func setattrlistTimes(path string, times []Timespec) error {
 
 	// order is mtime, atime: the opposite of Chtimes
 	attributes := [2]Timespec{times[1], times[0]}
-
-	const options = 0
+	options := 0
+	if flags&AT_SYMLINK_NOFOLLOW != 0 {
+		options |= FSOPT_NOFOLLOW
+	}
 	_, _, e1 := Syscall6(
 		SYS_SETATTRLIST,
 		uintptr(unsafe.Pointer(_p0)),

+ 1 - 1
unix/syscall_dragonfly.go

@@ -125,7 +125,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	return
 }
 
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
 	// used on Darwin for UtimesNano
 	return ENOSYS
 }

+ 1 - 1
unix/syscall_freebsd.go

@@ -120,7 +120,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	return
 }
 
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
 	// used on Darwin for UtimesNano
 	return ENOSYS
 }

+ 1 - 1
unix/syscall_netbsd.go

@@ -124,7 +124,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 	return -1, ENOSYS
 }
 
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
 	// used on Darwin for UtimesNano
 	return ENOSYS
 }

+ 1 - 1
unix/syscall_openbsd.go

@@ -102,7 +102,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	return
 }
 
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
 	// used on Darwin for UtimesNano
 	return ENOSYS
 }

+ 5 - 0
unix/zerrors_darwin_386.go

@@ -470,6 +470,11 @@ const (
 	FF1                               = 0x4000
 	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
+	FSOPT_ATTR_CMN_EXTENDED           = 0x20
+	FSOPT_NOFOLLOW                    = 0x1
+	FSOPT_NOINMEMUPDATE               = 0x2
+	FSOPT_PACK_INVAL_ATTRS            = 0x8
+	FSOPT_REPORT_FULLSIZE             = 0x4
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
 	F_ADDFILESIGS_RETURN              = 0x61

+ 5 - 0
unix/zerrors_darwin_amd64.go

@@ -470,6 +470,11 @@ const (
 	FF1                               = 0x4000
 	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
+	FSOPT_ATTR_CMN_EXTENDED           = 0x20
+	FSOPT_NOFOLLOW                    = 0x1
+	FSOPT_NOINMEMUPDATE               = 0x2
+	FSOPT_PACK_INVAL_ATTRS            = 0x8
+	FSOPT_REPORT_FULLSIZE             = 0x4
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
 	F_ADDFILESIGS_RETURN              = 0x61

+ 5 - 0
unix/zerrors_darwin_arm.go

@@ -470,6 +470,11 @@ const (
 	FF1                               = 0x4000
 	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
+	FSOPT_ATTR_CMN_EXTENDED           = 0x20
+	FSOPT_NOFOLLOW                    = 0x1
+	FSOPT_NOINMEMUPDATE               = 0x2
+	FSOPT_PACK_INVAL_ATTRS            = 0x8
+	FSOPT_REPORT_FULLSIZE             = 0x4
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
 	F_ADDFILESIGS_RETURN              = 0x61

+ 5 - 0
unix/zerrors_darwin_arm64.go

@@ -470,6 +470,11 @@ const (
 	FF1                               = 0x4000
 	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
+	FSOPT_ATTR_CMN_EXTENDED           = 0x20
+	FSOPT_NOFOLLOW                    = 0x1
+	FSOPT_NOINMEMUPDATE               = 0x2
+	FSOPT_PACK_INVAL_ATTRS            = 0x8
+	FSOPT_REPORT_FULLSIZE             = 0x4
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
 	F_ADDFILESIGS_RETURN              = 0x61