From 3c2dbca9adf8fd02d8c06de66fbb45dcab658c70 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Tue, 7 May 2024 03:20:44 +0100 Subject: [PATCH] Add methods taking file descriptor as OwnedFd. (#641) The OwnedFd type confers ownership of the file descriptor, so these can be safe methods rather than relying on the caller not to use the file descriptor anywhere else after making the call. Signed-off-by: Andrew Walbran --- src/channel.rs | 20 ++++++++++++++++++-- src/server.rs | 13 +++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/channel.rs b/src/channel.rs index 298334ee..118f1a31 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -495,7 +495,7 @@ impl ChannelBuilder { self.build_args() } - /// Build an [`Channel`] that connects to a specific address. + /// Build a [`Channel`] that connects to a specific address. pub fn connect(mut self, addr: &str) -> Channel { let args = self.prepare_connect_args(); let addr = CString::new(addr).unwrap(); @@ -509,7 +509,7 @@ impl ChannelBuilder { unsafe { Channel::new(self.env.pick_cq(), self.env, channel) } } - /// Build an [`Channel`] taking over an established connection from + /// Build a [`Channel`] taking over an established connection from /// a file descriptor. The target string given is purely informative to /// describe the endpoint of the connection. Takes ownership of the given /// file descriptor and will close it when the connection is closed. @@ -535,6 +535,22 @@ impl ChannelBuilder { Channel::new(self.env.pick_cq(), self.env, channel) } + + /// Build a [`Channel`] taking over an established connection from a file + /// descriptor. The target string given is purely informative to describe + /// the endpoint of the connection. Takes ownership of the given file + /// descriptor and will close it when the connection is closed. The file + /// descriptor must correspond to a connected stream socket. + /// + /// This function is available on posix systems only. + #[cfg(unix)] + pub fn connect_from_ownedfd(self, target: &str, fd: ::std::os::fd::OwnedFd) -> Channel { + use std::os::fd::IntoRawFd; + + // SAFETY: `OwnedFd` confers ownership of the file descriptor, so it + // won't be accessed by other code. + unsafe { self.connect_from_fd(target, fd.into_raw_fd()) } + } } #[cfg(feature = "_secure")] diff --git a/src/server.rs b/src/server.rs index 6915ed1a..a406bb43 100644 --- a/src/server.rs +++ b/src/server.rs @@ -475,6 +475,19 @@ impl Server { let mut creds = ServerCredentials::insecure(); grpcio_sys::grpc_server_add_channel_from_fd(self.core.server, fd, creds.as_mut_ptr()) } + + /// Add an RPC channel for an established connection represented as a file + /// descriptor. The file descriptor must correspond to a connected stream + /// socket. Takes ownership of the file descriptor, closing it when channel + /// is closed. + #[cfg(unix)] + pub fn add_channel_from_ownedfd(&mut self, fd: ::std::os::fd::OwnedFd) { + use std::os::fd::IntoRawFd; + + // SAFETY: `OwnedFd` confers ownership of the file descriptor, so it + // won't be accessed by other code. + unsafe { self.add_channel_from_fd(fd.into_raw_fd()) } + } } impl Drop for Server {