From 626ee8cfbb6dd48d1dc6ee35f87fbe5417d08c8f Mon Sep 17 00:00:00 2001 From: WGH Date: Sun, 5 Apr 2026 00:16:33 +0300 Subject: [PATCH] Implement IntoRawFd for Socket This is useful for cases when you initialize a socket outside async runtime (e.g. to create netlink socket in the parent namespace before doing unshare syscall), and wrap it into async socket later on. let mut sock = Socket::new(NETLINK_ROUTE).unwrap(); let addr = SocketAddr::new(0, 0); sock.bind(&addr).unwrap(); for group in GROUPS { sock.add_membership(*group as u32).unwrap(); } // do some unsafe single-threaded things like switch namespaces here, // and then initialize async runtime let sock = unsafe { TokioSocket::from_raw_fd(sock.into_raw_fd()) }; let (conn, _handle, mut messages) = rtnetlink::from_socket(sock); tokio::spawn(conn); while let Some((message, _)) = messages.next().await { dbg!(message); } --- src/socket.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/socket.rs b/src/socket.rs index f9bcb32..ecf0838 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -4,7 +4,7 @@ use std::{ io::{Error, Result}, mem, os::{ - fd::{AsFd, BorrowedFd, FromRawFd}, + fd::{AsFd, BorrowedFd, FromRawFd, IntoRawFd}, unix::io::{AsRawFd, RawFd}, }, }; @@ -69,6 +69,14 @@ impl AsFd for Socket { } } +impl IntoRawFd for Socket { + fn into_raw_fd(self) -> RawFd { + let fd = self.0; + std::mem::forget(self); + fd + } +} + impl FromRawFd for Socket { unsafe fn from_raw_fd(fd: RawFd) -> Self { Socket(fd)