Files
wazero/internal/platform/futimens_linux.go
Crypt Keeper 4d90a5c364 platform: Allows sysfs to implement utimens natively (#1215)
platform: Allows sysfs to implement utimesns natively

This moves away from `syscall.UtimesNano` as it has intentionally
avoided common features in POSIX, such as handling UTIME_NOW and
UTIME_OMIT. When we eventually expose this API, users will be free to
override `UTIME_NOW` with a fake clock, possibly the same that was
supplied to wazero's `ModuleConfig`.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-03-09 13:14:09 +08:00

44 lines
1.1 KiB
Go

package platform
import (
"syscall"
"unsafe"
_ "unsafe" // for go:linkname
)
const (
_AT_FDCWD = -0x64
_AT_SYMLINK_NOFOLLOW = 0x100
_UTIME_NOW = (1 << 30) - 1
_UTIME_OMIT = (1 << 30) - 2
SupportsSymlinkNoFollow = true
)
func utimens(path string, times *[2]syscall.Timespec, symlinkFollow bool) (err error) {
var flags int
if !symlinkFollow {
flags = _AT_SYMLINK_NOFOLLOW
}
var _p0 *byte
_p0, err = syscall.BytePtrFromString(path)
if err != nil {
return
}
return utimensat(_AT_FDCWD, uintptr(unsafe.Pointer(_p0)), times, flags)
}
// On linux, implement futimens via utimensat with the NUL path.
func futimens(fd uintptr, times *[2]syscall.Timespec) error {
return utimensat(int(fd), 0 /* NUL */, times, 0)
}
// utimensat is like syscall.utimensat special-cased to accept a NUL string for the path value.
func utimensat(dirfd int, strPtr uintptr, times *[2]syscall.Timespec, flags int) (err error) {
_, _, e1 := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirfd), strPtr, uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
if e1 != 0 {
err = e1
}
return
}