github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/sysfs/futimens_linux.go (about)

     1  //go:build !tinygo
     2  
     3  package sysfs
     4  
     5  import (
     6  	"syscall"
     7  	"unsafe"
     8  	_ "unsafe"
     9  
    10  	experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
    11  )
    12  
    13  const (
    14  	_AT_FDCWD   = -0x64
    15  	_UTIME_OMIT = (1 << 30) - 2
    16  )
    17  
    18  func utimens(path string, atim, mtim int64) experimentalsys.Errno {
    19  	times := timesToTimespecs(atim, mtim)
    20  	if times == nil {
    21  		return 0
    22  	}
    23  
    24  	var flags int
    25  	var _p0 *byte
    26  	_p0, err := syscall.BytePtrFromString(path)
    27  	if err == nil {
    28  		err = utimensat(_AT_FDCWD, uintptr(unsafe.Pointer(_p0)), times, flags)
    29  	}
    30  	return experimentalsys.UnwrapOSError(err)
    31  }
    32  
    33  // On linux, implement futimens via utimensat with the NUL path.
    34  func futimens(fd uintptr, atim, mtim int64) experimentalsys.Errno {
    35  	times := timesToTimespecs(atim, mtim)
    36  	if times == nil {
    37  		return 0
    38  	}
    39  	return experimentalsys.UnwrapOSError(utimensat(int(fd), 0 /* NUL */, times, 0))
    40  }
    41  
    42  // utimensat is like syscall.utimensat special-cased to accept a NUL string for the path value.
    43  func utimensat(dirfd int, strPtr uintptr, times *[2]syscall.Timespec, flags int) (err error) {
    44  	_, _, e1 := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirfd), strPtr, uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
    45  	if e1 != 0 {
    46  		err = e1
    47  	}
    48  	return
    49  }