diff --git a/src/call.rs b/src/call.rs index e6dfb95ea7..53ec5a530b 100644 --- a/src/call.rs +++ b/src/call.rs @@ -8,6 +8,11 @@ use super::{ use core::mem; +/// Close a file descriptor +pub fn close(fd: usize) -> Result { + unsafe { syscall1(SYS_CLOSE, fd) } +} + /// Get the current system time pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result { unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) } @@ -18,6 +23,11 @@ pub fn dup_into(fd: usize, out: usize, buf: &[u8]) -> Result { unsafe { syscall4(SYS_DUP_INTO, fd, buf.as_ptr() as usize, buf.len(), out) } } +/// Copy and transform a file descriptor, letting the kernel allocate the new fd +pub fn dup(fd: usize, buf: &[u8]) -> Result { + unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } +} + /// Copy and transform a file descriptor pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result { unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) } @@ -191,6 +201,40 @@ pub fn openat_into>( } } +/// Open a file at a specific path, letting the kernel allocate the new fd +pub fn openat>(fd: usize, path: T, flags: usize, fcntl_flags: usize) -> Result { + let path = path.as_ref(); + unsafe { + syscall5( + SYS_OPENAT, + fd, + path.as_ptr() as usize, + path.len(), + flags, + fcntl_flags, + ) + } +} + +/// Send a file descriptor to another process via a socket +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 usize, + ) + } + #[cfg(target_pointer_width = "64")] + unsafe { + syscall4(SYS_SENDFD, receiver_socket, fd, flags, arg as usize) + } +} + /// Remove a file at at specific path pub fn unlinkat>(fd: usize, path: T, flags: usize) -> Result { let path = path.as_ref(); diff --git a/src/number.rs b/src/number.rs index faf0b67421..9992b7189d 100644 --- a/src/number.rs +++ b/src/number.rs @@ -10,9 +10,10 @@ pub const SYS_ARG_PATH: usize = 0x0300_0000; pub const SYS_RET: usize = 0x00F0_0000; pub const SYS_RET_FILE: usize = 0x0010_0000; +/// Upstream 0.9.0 `openat_into` (caller supplies target fd number). pub const SYS_OPENAT_INTO: usize = SYS_CLASS_PATH | SYS_RET_FILE | 987; -/// Red Bear alias for the legacy SYS_OPENAT name (upstream 0.9.0 renamed to SYS_OPENAT_INTO). -pub const SYS_OPENAT: usize = SYS_OPENAT_INTO; +/// Legacy Red Bear `openat` (kernel allocates a new fd). +pub const SYS_OPENAT: usize = SYS_CLASS_PATH | SYS_RET_FILE | 7; /// Red Bear: preserve legacy SYS_OPENAT_WITH_FILTER (upstream 0.9.0 removed it; retained for kernel/userspace ABI). pub const SYS_OPENAT_WITH_FILTER: usize = SYS_CLASS_PATH | SYS_RET_FILE | 985; pub const SYS_UNLINKAT: usize = SYS_CLASS_PATH | 263; @@ -20,9 +21,10 @@ pub const SYS_UNLINKAT: usize = SYS_CLASS_PATH | 263; pub const SYS_UNLINKAT_WITH_FILTER: usize = SYS_CLASS_PATH | 986; pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; +/// Upstream 0.9.0 `dup_into` (caller supplies target fd number). pub const SYS_DUP_INTO: usize = SYS_CLASS_FILE | SYS_RET_FILE | 988; -/// Red Bear alias for the legacy SYS_DUP name (upstream 0.9.0 renamed to SYS_DUP_INTO). -pub const SYS_DUP: usize = SYS_DUP_INTO; +/// Legacy Red Bear `dup` (kernel allocates a new fd). +pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63; /// Red Bear: preserve legacy SYS_SENDFD (upstream 0.9.0 removed it; retained for kernel/userspace ABI). pub const SYS_SENDFD: usize = SYS_CLASS_FILE | 34;