mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-03 15:47:35 -04:00
unix: add openat2 for linux
openat2 is a new syscall added to Linux 5.6. It provides a superset of openat(2) functionality, providing a way to extend it in the future, and (for now) adding flags telling the kernel how to resolve the path. For more info on openat2, see https://lwn.net/Articles/803237/ A primitive test case is added to check that Openat2 works as it should. Tested to skip on kernel 5.5 and pass on 5.6. Change-Id: Ib8bbd71791762f043200543cecdea16d2fd3c81d Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com> Reviewed-on: https://go-review.googlesource.com/c/sys/+/227280 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
committed by
Tobias Klauser
parent
c3d8025017
commit
c6e801f48b
@@ -106,6 +106,7 @@ struct termios2 {
|
|||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/openat2.h>
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
@@ -833,6 +834,18 @@ const (
|
|||||||
AT_EACCESS = C.AT_EACCESS
|
AT_EACCESS = C.AT_EACCESS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OpenHow C.struct_open_how
|
||||||
|
|
||||||
|
const SizeofOpenHow = C.sizeof_struct_open_how
|
||||||
|
|
||||||
|
const (
|
||||||
|
RESOLVE_BENEATH = C.RESOLVE_BENEATH
|
||||||
|
RESOLVE_IN_ROOT = C.RESOLVE_IN_ROOT
|
||||||
|
RESOLVE_NO_MAGICLINKS = C.RESOLVE_NO_MAGICLINKS
|
||||||
|
RESOLVE_NO_SYMLINKS = C.RESOLVE_NO_SYMLINKS
|
||||||
|
RESOLVE_NO_XDEV = C.RESOLVE_NO_XDEV
|
||||||
|
)
|
||||||
|
|
||||||
type PollFd C.struct_pollfd
|
type PollFd C.struct_pollfd
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -133,6 +133,12 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
|
|||||||
return openat(dirfd, path, flags|O_LARGEFILE, mode)
|
return openat(dirfd, path, flags|O_LARGEFILE, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error)
|
||||||
|
|
||||||
|
func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
|
||||||
|
return openat2(dirfd, path, how, SizeofOpenHow)
|
||||||
|
}
|
||||||
|
|
||||||
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
||||||
|
|
||||||
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
||||||
|
|||||||
@@ -663,3 +663,24 @@ func TestPrctlRetInt(t *testing.T) {
|
|||||||
t.Fatalf("unexpected return from prctl; got %v, expected %v", v, 1)
|
t.Fatalf("unexpected return from prctl; got %v, expected %v", v, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOpenat2(t *testing.T) {
|
||||||
|
how := &unix.OpenHow{
|
||||||
|
Flags: unix.O_RDONLY,
|
||||||
|
Resolve: unix.RESOLVE_NO_MAGICLINKS,
|
||||||
|
}
|
||||||
|
fd, err := unix.Openat2(-1, "/proc/self/fd/1", how)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
unix.Close(fd)
|
||||||
|
t.Fatal("expected ELOOP, got nil")
|
||||||
|
case unix.ELOOP:
|
||||||
|
return
|
||||||
|
case unix.ENOSYS:
|
||||||
|
t.Skip("old kernel? (need Linux >= 5.6)")
|
||||||
|
case unix.ENOENT:
|
||||||
|
t.Skipf("openat2: %v, skipping test", err)
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected error from openat2: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,6 +83,22 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r0, _, e1 := Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(open_how)), uintptr(size), 0, 0)
|
||||||
|
fd = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
||||||
r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
|
r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
|
||||||
n = int(r0)
|
n = int(r0)
|
||||||
|
|||||||
@@ -691,6 +691,22 @@ const (
|
|||||||
AT_EACCESS = 0x200
|
AT_EACCESS = 0x200
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OpenHow struct {
|
||||||
|
Flags uint64
|
||||||
|
Mode uint64
|
||||||
|
Resolve uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
const SizeofOpenHow = 0x18
|
||||||
|
|
||||||
|
const (
|
||||||
|
RESOLVE_BENEATH = 0x8
|
||||||
|
RESOLVE_IN_ROOT = 0x10
|
||||||
|
RESOLVE_NO_MAGICLINKS = 0x2
|
||||||
|
RESOLVE_NO_SYMLINKS = 0x4
|
||||||
|
RESOLVE_NO_XDEV = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
type PollFd struct {
|
type PollFd struct {
|
||||||
Fd int32
|
Fd int32
|
||||||
Events int16
|
Events int16
|
||||||
|
|||||||
Reference in New Issue
Block a user