mirror of
https://github.com/golang/sys.git
synced 2026-02-08 19:56:04 +03:00
unix: add utimensat libc wrapper on darwin
Direct syscalls are no longer supported on darwin (CL 250437), so utimensat can be implemented as a wrapper around the libc function. The utimensat function was added in macOS 10.13 and Go 1.17 dropped support for macOS 10.12. This also allows to drop the fallback to setattrlistTimes which was used to set timestamps with nanosecond resolution before utimensat could be used, see golang/go#22528 and CL 74952. Change-Id: I206291277e6f7200ca7a659e29075968647779a6 Reviewed-on: https://go-review.googlesource.com/c/sys/+/251737 Trust: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
committed by
Tobias Klauser
parent
36772127a2
commit
530d0810a4
@@ -118,7 +118,6 @@ var darwinTests = [...]darwinTest{
|
||||
{"sendfile", libc_sendfile_trampoline_addr},
|
||||
{"sendmsg", libc_sendmsg_trampoline_addr},
|
||||
{"sendto", libc_sendto_trampoline_addr},
|
||||
{"setattrlist", libc_setattrlist_trampoline_addr},
|
||||
{"setegid", libc_setegid_trampoline_addr},
|
||||
{"seteuid", libc_seteuid_trampoline_addr},
|
||||
{"setgid", libc_setgid_trampoline_addr},
|
||||
@@ -154,6 +153,7 @@ var darwinTests = [...]darwinTest{
|
||||
{"unlink", libc_unlink_trampoline_addr},
|
||||
{"unlinkat", libc_unlinkat_trampoline_addr},
|
||||
{"unmount", libc_unmount_trampoline_addr},
|
||||
{"utimensat", libc_utimensat_trampoline_addr},
|
||||
{"utimes", libc_utimes_trampoline_addr},
|
||||
{"wait4", libc_wait4_trampoline_addr},
|
||||
{"write", libc_write_trampoline_addr},
|
||||
|
||||
@@ -118,7 +118,6 @@ var darwinTests = [...]darwinTest{
|
||||
{"sendfile", libc_sendfile_trampoline_addr},
|
||||
{"sendmsg", libc_sendmsg_trampoline_addr},
|
||||
{"sendto", libc_sendto_trampoline_addr},
|
||||
{"setattrlist", libc_setattrlist_trampoline_addr},
|
||||
{"setegid", libc_setegid_trampoline_addr},
|
||||
{"seteuid", libc_seteuid_trampoline_addr},
|
||||
{"setgid", libc_setgid_trampoline_addr},
|
||||
@@ -154,6 +153,7 @@ var darwinTests = [...]darwinTest{
|
||||
{"unlink", libc_unlink_trampoline_addr},
|
||||
{"unlinkat", libc_unlinkat_trampoline_addr},
|
||||
{"unmount", libc_unmount_trampoline_addr},
|
||||
{"utimensat", libc_utimensat_trampoline_addr},
|
||||
{"utimes", libc_utimes_trampoline_addr},
|
||||
{"wait4", libc_wait4_trampoline_addr},
|
||||
{"write", libc_write_trampoline_addr},
|
||||
|
||||
@@ -553,12 +553,7 @@ func UtimesNano(path string, ts []Timespec) error {
|
||||
if len(ts) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
// Darwin setattrlist can set nanosecond timestamps
|
||||
err := setattrlistTimes(path, ts, 0)
|
||||
if err != ENOSYS {
|
||||
return err
|
||||
}
|
||||
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
if err != ENOSYS {
|
||||
return err
|
||||
}
|
||||
@@ -578,10 +573,6 @@ 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)
|
||||
}
|
||||
|
||||
|
||||
@@ -141,16 +141,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
|
||||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
|
||||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
|
||||
|
||||
type attrList struct {
|
||||
bitmapCount uint16
|
||||
_ uint16
|
||||
CommonAttr uint32
|
||||
VolAttr uint32
|
||||
DirAttr uint32
|
||||
FileAttr uint32
|
||||
Forkattr uint32
|
||||
}
|
||||
|
||||
//sysnb pipe(p *[2]int32) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
@@ -282,36 +272,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
||||
return flistxattr(fd, xattrPointer(dest), len(dest), 0)
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
_p0, err := BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var attrList attrList
|
||||
attrList.bitmapCount = ATTR_BIT_MAP_COUNT
|
||||
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME
|
||||
|
||||
// order is mtime, atime: the opposite of Chtimes
|
||||
attributes := [2]Timespec{times[1], times[0]}
|
||||
options := 0
|
||||
if flags&AT_SYMLINK_NOFOLLOW != 0 {
|
||||
options |= FSOPT_NOFOLLOW
|
||||
}
|
||||
return setattrlist(
|
||||
_p0,
|
||||
unsafe.Pointer(&attrList),
|
||||
unsafe.Pointer(&attributes),
|
||||
unsafe.Sizeof(attributes),
|
||||
options)
|
||||
}
|
||||
|
||||
//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
|
||||
|
||||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
|
||||
// Darwin doesn't support SYS_UTIMENSAT
|
||||
return ENOSYS
|
||||
}
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
||||
|
||||
/*
|
||||
* Wrapped
|
||||
|
||||
@@ -169,11 +169,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
||||
@@ -194,11 +194,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
||||
@@ -163,11 +163,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||
return -1, ENOSYS
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
||||
@@ -149,11 +149,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
||||
@@ -643,17 +643,22 @@ var libc_flistxattr_trampoline_addr uintptr
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
|
||||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_setattrlist_trampoline_addr uintptr
|
||||
var libc_utimensat_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic libc_utimensat utimensat "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
|
||||
@@ -228,11 +228,11 @@ TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0
|
||||
GLOBL ·libc_flistxattr_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB)
|
||||
|
||||
TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_setattrlist(SB)
|
||||
TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimensat(SB)
|
||||
|
||||
GLOBL ·libc_setattrlist_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB)
|
||||
GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
|
||||
|
||||
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_fcntl(SB)
|
||||
|
||||
@@ -643,17 +643,22 @@ var libc_flistxattr_trampoline_addr uintptr
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
|
||||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_setattrlist_trampoline_addr uintptr
|
||||
var libc_utimensat_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic libc_utimensat utimensat "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
|
||||
@@ -228,11 +228,11 @@ TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0
|
||||
GLOBL ·libc_flistxattr_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB)
|
||||
|
||||
TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_setattrlist(SB)
|
||||
TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimensat(SB)
|
||||
|
||||
GLOBL ·libc_setattrlist_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB)
|
||||
GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
|
||||
|
||||
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_fcntl(SB)
|
||||
|
||||
Reference in New Issue
Block a user