github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/futimens_windows.go (about)

     1  package sysfs
     2  
     3  import (
     4  	"syscall"
     5  
     6  	"github.com/bananabytelabs/wazero/experimental/sys"
     7  	"github.com/bananabytelabs/wazero/internal/platform"
     8  )
     9  
    10  func utimens(path string, atim, mtim int64) sys.Errno {
    11  	return chtimes(path, atim, mtim)
    12  }
    13  
    14  func futimens(fd uintptr, atim, mtim int64) error {
    15  	// Before Go 1.20, ERROR_INVALID_HANDLE was returned for too many reasons.
    16  	// Kick out so that callers can use path-based operations instead.
    17  	if !platform.IsAtLeastGo120 {
    18  		return sys.ENOSYS
    19  	}
    20  
    21  	// Per docs, zero isn't a valid timestamp as it cannot be differentiated
    22  	// from nil. In both cases, it is a marker like sys.UTIME_OMIT.
    23  	// See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime
    24  	a, w := timespecToFiletime(atim, mtim)
    25  
    26  	if a == nil && w == nil {
    27  		return nil // both omitted, so nothing to change
    28  	}
    29  
    30  	// Attempt to get the stat by handle, which works for normal files
    31  	h := syscall.Handle(fd)
    32  
    33  	// Note: This returns ERROR_ACCESS_DENIED when the input is a directory.
    34  	return syscall.SetFileTime(h, nil, a, w)
    35  }
    36  
    37  func timespecToFiletime(atim, mtim int64) (a, w *syscall.Filetime) {
    38  	a = timespecToFileTime(atim)
    39  	w = timespecToFileTime(mtim)
    40  	return
    41  }
    42  
    43  func timespecToFileTime(tim int64) *syscall.Filetime {
    44  	if tim == sys.UTIME_OMIT {
    45  		return nil
    46  	}
    47  	ft := syscall.NsecToFiletime(tim)
    48  	return &ft
    49  }