diff --git a/Cargo.toml b/Cargo.toml index b530bf55..cb287d2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,4 +46,4 @@ features = [ [features] # Enable all API, even ones not available on all OSs. -all = [] +all = [] \ No newline at end of file diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 13e09662..d2b6f9e8 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -37,7 +37,7 @@ use std::os::unix::ffi::OsStrExt; ) ))] use std::os::unix::io::RawFd; -use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; +use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}; #[cfg(feature = "all")] use std::os::unix::net::{UnixDatagram, UnixListener, UnixStream}; #[cfg(feature = "all")] @@ -2031,6 +2031,29 @@ impl FromRawFd for crate::Socket { } } +#[cfg_attr(docsrs, doc(cfg(unix)))] +impl AsFd for crate::Socket { + fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: lifetime is bound by "self" + unsafe { BorrowedFd::borrow_raw(self.as_raw()) } + } +} + +#[cfg_attr(docsrs, doc(cfg(unix)))] +impl From for crate::Socket { + fn from(fd: OwnedFd) -> Self { + Self::from_raw(fd.into_raw_fd()) + } +} + +#[cfg_attr(docsrs, doc(cfg(unix)))] +impl From for OwnedFd { + fn from(sock: crate::Socket) -> Self { + // SAFETY: sock.into_raw() is a valid fd + unsafe { OwnedFd::from_raw_fd(sock.into_raw()) } + } +} + #[cfg(feature = "all")] from!(UnixStream, crate::Socket); #[cfg(feature = "all")] diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 9ca6abdf..20174e56 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -11,7 +11,9 @@ use std::io::{self, IoSlice}; use std::marker::PhantomData; use std::mem::{self, size_of, MaybeUninit}; use std::net::{self, Ipv4Addr, Ipv6Addr, Shutdown}; -use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; +use std::os::windows::io::{ + AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, +}; use std::sync::Once; use std::time::{Duration, Instant}; use std::{process, ptr, slice}; @@ -818,6 +820,26 @@ impl FromRawSocket for crate::Socket { } } +impl AsSocket for crate::Socket { + fn as_socket(&self) -> BorrowedSocket<'_> { + // SAFETY: lifetime is bound by "self" + unsafe { BorrowedSocket::borrow_raw(self.as_raw() as RawSocket) } + } +} + +impl From for crate::Socket { + fn from(fd: OwnedSocket) -> Self { + Self::from_raw(fd.into_raw_socket() as Socket) + } +} + +impl From for OwnedSocket { + fn from(sock: crate::Socket) -> Self { + // SAFETY: sock.into_raw() is a valid fd + unsafe { OwnedSocket::from_raw_socket(sock.into_raw() as RawSocket) } + } +} + #[test] fn in_addr_convertion() { let ip = Ipv4Addr::new(127, 0, 0, 1);