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>
diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh
index c7a7473..4ddd4ff 100755
--- a/unix/mkerrors.sh
+++ b/unix/mkerrors.sh
@@ -426,6 +426,7 @@
$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]+$/ ||
diff --git a/unix/syscall_bsd.go b/unix/syscall_bsd.go
index 3906090..47b0598 100644
--- a/unix/syscall_bsd.go
+++ b/unix/syscall_bsd.go
@@ -571,7 +571,7 @@
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 @@
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)
}
diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go
index edcab03..9a6783e 100644
--- a/unix/syscall_darwin.go
+++ b/unix/syscall_darwin.go
@@ -187,7 +187,7 @@
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 @@
// 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)),
diff --git a/unix/syscall_dragonfly.go b/unix/syscall_dragonfly.go
index 63ee371..25eeada 100644
--- a/unix/syscall_dragonfly.go
+++ b/unix/syscall_dragonfly.go
@@ -125,7 +125,7 @@
return
}
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
diff --git a/unix/syscall_freebsd.go b/unix/syscall_freebsd.go
index 823d53a..a82ce12 100644
--- a/unix/syscall_freebsd.go
+++ b/unix/syscall_freebsd.go
@@ -120,7 +120,7 @@
return
}
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
diff --git a/unix/syscall_netbsd.go b/unix/syscall_netbsd.go
index 3e28aa1..4455eff 100644
--- a/unix/syscall_netbsd.go
+++ b/unix/syscall_netbsd.go
@@ -124,7 +124,7 @@
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
}
diff --git a/unix/syscall_openbsd.go b/unix/syscall_openbsd.go
index fe05375..2158196 100644
--- a/unix/syscall_openbsd.go
+++ b/unix/syscall_openbsd.go
@@ -102,7 +102,7 @@
return
}
-func setattrlistTimes(path string, times []Timespec) error {
+func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
diff --git a/unix/zerrors_darwin_386.go b/unix/zerrors_darwin_386.go
index b238a03..ac581f3 100644
--- a/unix/zerrors_darwin_386.go
+++ b/unix/zerrors_darwin_386.go
@@ -470,6 +470,11 @@
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
diff --git a/unix/zerrors_darwin_amd64.go b/unix/zerrors_darwin_amd64.go
index f7e4e3a..2ba407a 100644
--- a/unix/zerrors_darwin_amd64.go
+++ b/unix/zerrors_darwin_amd64.go
@@ -470,6 +470,11 @@
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
diff --git a/unix/zerrors_darwin_arm.go b/unix/zerrors_darwin_arm.go
index b5c7999..f4a2fde 100644
--- a/unix/zerrors_darwin_arm.go
+++ b/unix/zerrors_darwin_arm.go
@@ -470,6 +470,11 @@
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
diff --git a/unix/zerrors_darwin_arm64.go b/unix/zerrors_darwin_arm64.go
index bb78e53..4c2e696 100644
--- a/unix/zerrors_darwin_arm64.go
+++ b/unix/zerrors_darwin_arm64.go
@@ -470,6 +470,11 @@
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