From 57f3b7ab6588449a1926e1b96adbeb27536bdb0f Mon Sep 17 00:00:00 2001 From: Asakura Mizu Date: Wed, 31 Jul 2024 17:36:53 +0800 Subject: [PATCH] feat(net): add `get_socket_option` on `Socket` --- compio-net/src/socket.rs | 45 +++++++++++++++++++++++++++++++++++++++- compio-net/src/udp.rs | 5 +++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/compio-net/src/socket.rs b/compio-net/src/socket.rs index d7bc5a8d..74d8b7ee 100644 --- a/compio-net/src/socket.rs +++ b/compio-net/src/socket.rs @@ -1,4 +1,8 @@ -use std::{future::Future, io, mem::ManuallyDrop}; +use std::{ + future::Future, + io, + mem::{ManuallyDrop, MaybeUninit}, +}; use compio_buf::{BufResult, IntoInner, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut}; #[cfg(unix)] @@ -319,6 +323,45 @@ impl Socket { compio_runtime::submit(op).await.into_inner() } + #[cfg(unix)] + pub fn get_socket_option(&self, level: i32, name: i32) -> io::Result { + let mut value: MaybeUninit = MaybeUninit::uninit(); + let mut len = size_of::() as libc::socklen_t; + syscall!(libc::getsockopt( + self.socket.as_raw_fd(), + level, + name, + value.as_mut_ptr() as _, + &mut len + )) + .map(|_| { + debug_assert_eq!(len as usize, size_of::()); + // SAFETY: The value is initialized by `getsockopt`. + unsafe { value.assume_init() } + }) + } + + #[cfg(windows)] + pub fn get_socket_option(&self, level: i32, name: i32) -> io::Result { + let mut value: MaybeUninit = MaybeUninit::uninit(); + let mut len = size_of::() as i32; + syscall!( + SOCKET, + windows_sys::Win32::Networking::WinSock::getsockopt( + self.socket.as_raw_fd() as _, + level, + name, + value.as_mut_ptr() as _, + &mut len + ) + ) + .map(|_| { + debug_assert_eq!(len as usize, size_of::()); + // SAFETY: The value is initialized by `getsockopt`. + unsafe { value.assume_init() } + }) + } + #[cfg(unix)] pub fn set_socket_option(&self, level: i32, name: i32, value: &T) -> io::Result<()> { syscall!(libc::setsockopt( diff --git a/compio-net/src/udp.rs b/compio-net/src/udp.rs index 13e59d73..d0855833 100644 --- a/compio-net/src/udp.rs +++ b/compio-net/src/udp.rs @@ -316,6 +316,11 @@ impl UdpSocket { .await } + /// Gets a socket option. + pub fn get_socket_option(&self, level: i32, name: i32) -> io::Result { + self.inner.get_socket_option(level, name) + } + /// Sets a socket option. pub fn set_socket_option(&self, level: i32, name: i32, value: &T) -> io::Result<()> { self.inner.set_socket_option(level, name, value)