implement futimens on Darwin and Linux (#1210)
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
34
internal/platform/utimes_darwin.go
Normal file
34
internal/platform/utimes_darwin.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func futimens(fd uintptr, atimeNsec, mtimeNsec int64) error {
|
||||
tv := []syscall.Timespec{
|
||||
syscall.NsecToTimespec(atimeNsec),
|
||||
syscall.NsecToTimespec(mtimeNsec),
|
||||
}
|
||||
|
||||
// Warning: futimens only exists since High Sierra (10.13).
|
||||
_, _, e1 := syscall_syscall6(libc_futimens_trampoline_addr, fd, uintptr(unsafe.Pointer(&tv[0])), 0, 0, 0, 0)
|
||||
if e1 != 0 {
|
||||
return e1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// libc_futimens_trampoline_addr is the address of the libc_futimens_trampoline symbol, defined in utimes_darwin.s
|
||||
// we use this value to invoke the syscall through syscall_syscall6 imported below
|
||||
var libc_futimens_trampoline_addr uintptr
|
||||
|
||||
// Imports the futimens symbol from libc as libc_futimens
|
||||
//go:cgo_import_dynamic libc_futimens futimens "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// syscall_syscall6 is a private symbol that we link below. We need to use this instead of syscall.Syscall6
|
||||
// because the public syscall.Syscall6 won't work when fn is an address
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
// Import syscall.syscall6 as syscall_syscall6.
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
8
internal/platform/utimes_darwin.s
Normal file
8
internal/platform/utimes_darwin.s
Normal file
@@ -0,0 +1,8 @@
|
||||
// lifted from golang.org/x/sys unix
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT libc_futimens_trampoline<>(SB), NOSPLIT, $0-0
|
||||
JMP libc_futimens(SB)
|
||||
|
||||
GLOBL ·libc_futimens_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_futimens_trampoline_addr(SB)/8, $libc_futimens_trampoline<>(SB)
|
||||
18
internal/platform/utimes_linux.go
Normal file
18
internal/platform/utimes_linux.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func futimens(fd uintptr, atimeNsec, mtimeNsec int64) error {
|
||||
times := []syscall.Timespec{
|
||||
syscall.NsecToTimespec(atimeNsec),
|
||||
syscall.NsecToTimespec(mtimeNsec),
|
||||
}
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, fd, uintptr(0), uintptr(unsafe.Pointer(×[0])), uintptr(0), 0, 0)
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func TestUtimesNano(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUtimesNanoFile(t *testing.T) {
|
||||
if !(runtime.GOOS == "windows" && IsGo120) {
|
||||
if !IsGo120 {
|
||||
t.Skip("TODO: implement futimens on darwin, freebsd, linux w/o CGO")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !windows
|
||||
//go:build !windows && !linux && !darwin
|
||||
|
||||
package platform
|
||||
|
||||
|
||||
Reference in New Issue
Block a user