From 06d569933f24af0c72b8bb2eb1aaa031113843fd Mon Sep 17 00:00:00 2001 From: 4lDO2 <4ldo2@protonmail.com> Date: Thu, 19 Oct 2023 15:00:28 +0000 Subject: [PATCH] Add SYS_SENDFD --- src/call.rs | 16 ++++++++++++++++ src/flag.rs | 29 +++++++++++++++++++++++++++++ src/number.rs | 2 ++ 3 files changed, 47 insertions(+) diff --git a/src/call.rs b/src/call.rs index 87ba8a980a..807b9491b9 100644 --- a/src/call.rs +++ b/src/call.rs @@ -362,3 +362,19 @@ pub fn write(fd: usize, buf: &[u8]) -> Result { pub fn sched_yield() -> Result { unsafe { syscall0(SYS_YIELD) } } + +/// Send a file descriptor `fd`, handled by the scheme providing `receiver_socket`. `flags` is +/// currently unused (must be zero), and `arg` is included in the scheme call. +/// +/// The scheme can return an arbitrary value. +pub fn sendfd(receiver_socket: usize, fd: usize, flags: usize, arg: u64) -> Result { + #[cfg(target_pointer_width = "32")] + unsafe { + syscall5(SYS_SENDFD, receiver_socket, fd, flags, arg as u32 as usize, (arg >> 32) as u32 as usize) + } + + #[cfg(target_pointer_width = "64")] + unsafe { + syscall4(SYS_SENDFD, receiver_socket, fd, flags, arg as usize) + } +} diff --git a/src/flag.rs b/src/flag.rs index 45a6e42e80..9c570e69bc 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -60,6 +60,35 @@ pub const SKMSG_FRETURNFD: usize = 0; // packet.uid:packet.gid = offset, packet.c = base address, packet.d = page count pub const SKMSG_PROVIDE_MMAP: usize = 1; +// packet.id provides state, packet.c = dest fd or pointer to dest fd, packet.d = flags +pub const SKMSG_FOBTAINFD: usize = 2; + +// TODO: Split SendFdFlags into caller flags and flags that the scheme receives? +bitflags::bitflags! { + pub struct SendFdFlags: usize { + /// If set, the kernel will enforce that the file descriptor is exclusively owned. + /// + /// That is, there will no longer exist any other reference to that FD when removed from + /// the file table (SYS_SENDFD always removes the FD from the file table, but without this + /// flag, it can be retained by SYS_DUPing it first). + const EXCLUSIVE = 1; + } +} +bitflags::bitflags! { + pub struct FobtainFdFlags: usize { + /// If set, `packet.c` specifies the destination file descriptor slot, otherwise the lowest + /// available slot will be selected, and placed in the usize pointed to by `packet.c`. + const MANUAL_FD = 1; + + // If set, the file descriptor received is guaranteed to be exclusively owned (by the file + // table the obtainer is running in). + const EXCLUSIVE = 2; + + // No, cloexec won't be stored in the kernel in the future, when the stable ABI is moved to + // relibc, so no flag for that! + } +} + bitflags! { pub struct MapFlags: usize { // TODO: Downgrade PROT_NONE to global constant? (bitflags specifically states zero flags diff --git a/src/number.rs b/src/number.rs index 056cfc76ab..ea956fc0c1 100644 --- a/src/number.rs +++ b/src/number.rs @@ -26,6 +26,8 @@ pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207; pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55; pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; +pub const SYS_SENDFD: usize = SYS_CLASS_FILE | 34; + // TODO: Rename FMAP/FUNMAP to MMAP/MUNMAP pub const SYS_FMAP_OLD: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 90; pub const SYS_FMAP: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 900;