Lindenii Project Forge
misc: Add Openat2
// Package misc provides miscellaneous functions. package misc
import ( "errors" "strings" ) // Copy_map the map src to dst without clearing existing items in dst.
func Copy_map[K comparable, V any](dst map[K]V, src map[K]V) { for k, v := range src { dst[k] = v } }
// String_to_byte_ptr returns a pointer to the first byte of a string. It // ensures that the returned pointer is null-terminated. func String_to_byte_ptr(s string) (*byte, error) { // If the string already contains a null then whoever attempts to // interpret this as a null-terminated string won't be able to see the // whole string. This is probably not expected by the caller. if strings.IndexByte(s, 0) != -1 { return nil, Err_null_byte } buf := make([]byte, len(s)+1) // Zeros them out... copy(buf, s) // ... so the last byte would be null. return &buf[0], nil } var Err_null_byte = errors.New("string contains null byte")
package misc import ( "syscall" "unsafe" ) const SYS_OPENAT2 = 437 type Open_how_t struct { Flags uint64 Mode uint64 Resolve uint64 } const ( RESOLVE_BENEATH = 0x8 RESOLVE_IN_ROOT = 0x10 RESOLVE_NO_MAGICLINKS = 0x2 RESOLVE_NO_SYMLINKS = 0x4 RESOLVE_NO_XDEV = 0x1 ) // See openat2(2) on Linux func Openat2(dirfd int, path string, open_how *Open_how_t, size int) (fd int, err error) { path_ptr, err := String_to_byte_ptr(path) if err != nil { return } _fd, _, errno := syscall.Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(path_ptr)), uintptr(unsafe.Pointer(open_how)), uintptr(size), 0, 0) fd = int(_fd) if errno != 0 { err = errno } return }