Skip to content

Commit

Permalink
net: add into_std for net types without it (#3509)
Browse files Browse the repository at this point in the history
  • Loading branch information
Darksonn authored Feb 6, 2021
1 parent 6fd9084 commit 58bd242
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 10 deletions.
43 changes: 42 additions & 1 deletion tokio/src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ impl TcpListener {
/// backing event loop. This allows configuration of options like
/// `SO_REUSEPORT`, binding to multiple addresses, etc.
///
///
/// # Examples
///
/// ```rust,no_run
Expand Down Expand Up @@ -221,6 +220,48 @@ impl TcpListener {
Ok(TcpListener { io })
}

/// Turn a [`tokio::net::TcpListener`] into a [`std::net::TcpListener`].
///
/// The returned [`std::net::TcpListener`] will have nonblocking mode set as
/// `true`. Use [`set_nonblocking`] to change the blocking mode if needed.
///
/// # Examples
///
/// ```rust,no_run
/// use std::error::Error;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn Error>> {
/// let tokio_listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?;
/// let std_listener = tokio_listener.into_std()?;
/// std_listener.set_nonblocking(false)?;
/// Ok(())
/// }
/// ```
///
/// [`tokio::net::TcpListener`]: TcpListener
/// [`std::net::TcpListener`]: std::net::TcpListener
/// [`set_nonblocking`]: fn@std::net::TcpListener::set_nonblocking
pub fn into_std(self) -> io::Result<std::net::TcpListener> {
#[cfg(unix)]
{
use std::os::unix::io::{FromRawFd, IntoRawFd};
self.io
.into_inner()
.map(|io| io.into_raw_fd())
.map(|raw_fd| unsafe { std::net::TcpListener::from_raw_fd(raw_fd) })
}

#[cfg(windows)]
{
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
self.io
.into_inner()
.map(|io| io.into_raw_socket())
.map(|raw_socket| unsafe { std::net::TcpListener::from_raw_socket(raw_socket) })
}
}

pub(crate) fn new(listener: mio::net::TcpListener) -> io::Result<TcpListener> {
let io = PollEvented::new(listener)?;
Ok(TcpListener { io })
Expand Down
11 changes: 5 additions & 6 deletions tokio/src/net/tcp/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::net::{Shutdown, SocketAddr};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket};

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
Expand Down Expand Up @@ -199,7 +194,7 @@ impl TcpStream {

/// Turn a [`tokio::net::TcpStream`] into a [`std::net::TcpStream`].
///
/// The returned [`std::net::TcpStream`] will have `nonblocking mode` set as `true`.
/// The returned [`std::net::TcpStream`] will have nonblocking mode set as `true`.
/// Use [`set_nonblocking`] to change the blocking mode if needed.
///
/// # Examples
Expand Down Expand Up @@ -234,6 +229,7 @@ impl TcpStream {
pub fn into_std(self) -> io::Result<std::net::TcpStream> {
#[cfg(unix)]
{
use std::os::unix::io::{FromRawFd, IntoRawFd};
self.io
.into_inner()
.map(|io| io.into_raw_fd())
Expand All @@ -242,6 +238,7 @@ impl TcpStream {

#[cfg(windows)]
{
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
self.io
.into_inner()
.map(|io| io.into_raw_socket())
Expand Down Expand Up @@ -932,11 +929,13 @@ impl TcpStream {
fn to_mio(&self) -> mio::net::TcpSocket {
#[cfg(windows)]
{
use std::os::windows::io::{AsRawSocket, FromRawSocket};
unsafe { mio::net::TcpSocket::from_raw_socket(self.as_raw_socket()) }
}

#[cfg(unix)]
{
use std::os::unix::io::{AsRawFd, FromRawFd};
unsafe { mio::net::TcpSocket::from_raw_fd(self.as_raw_fd()) }
}
}
Expand Down
42 changes: 42 additions & 0 deletions tokio/src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,48 @@ impl UdpSocket {
UdpSocket::new(io)
}

/// Turn a [`tokio::net::UdpSocket`] into a [`std::net::UdpSocket`].
///
/// The returned [`std::net::UdpSocket`] will have nonblocking mode set as
/// `true`. Use [`set_nonblocking`] to change the blocking mode if needed.
///
/// # Examples
///
/// ```rust,no_run
/// use std::error::Error;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn Error>> {
/// let tokio_socket = tokio::net::UdpSocket::bind("127.0.0.1:0").await?;
/// let std_socket = tokio_socket.into_std()?;
/// std_socket.set_nonblocking(false)?;
/// Ok(())
/// }
/// ```
///
/// [`tokio::net::UdpSocket`]: UdpSocket
/// [`std::net::UdpSocket`]: std::net::UdpSocket
/// [`set_nonblocking`]: fn@std::net::UdpSocket::set_nonblocking
pub fn into_std(self) -> io::Result<std::net::UdpSocket> {
#[cfg(unix)]
{
use std::os::unix::io::{FromRawFd, IntoRawFd};
self.io
.into_inner()
.map(|io| io.into_raw_fd())
.map(|raw_fd| unsafe { std::net::UdpSocket::from_raw_fd(raw_fd) })
}

#[cfg(windows)]
{
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
self.io
.into_inner()
.map(|io| io.into_raw_socket())
.map(|raw_socket| unsafe { std::net::UdpSocket::from_raw_socket(raw_socket) })
}
}

/// Returns the local address that this socket is bound to.
///
/// # Example
Expand Down
32 changes: 31 additions & 1 deletion tokio/src/net/unix/datagram/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::net::Shutdown;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::os::unix::net;
use std::path::Path;
use std::task::{Context, Poll};
Expand Down Expand Up @@ -376,6 +376,36 @@ impl UnixDatagram {
Ok(UnixDatagram { io })
}

/// Turn a [`tokio::net::UnixDatagram`] into a [`std::os::unix::net::UnixDatagram`].
///
/// The returned [`std::os::unix::net::UnixDatagram`] will have nonblocking
/// mode set as `true`. Use [`set_nonblocking`] to change the blocking mode
/// if needed.
///
/// # Examples
///
/// ```rust,no_run
/// use std::error::Error;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn Error>> {
/// let tokio_socket = tokio::net::UnixDatagram::bind("127.0.0.1:0")?;
/// let std_socket = tokio_socket.into_std()?;
/// std_socket.set_nonblocking(false)?;
/// Ok(())
/// }
/// ```
///
/// [`tokio::net::UnixDatagram`]: UnixDatagram
/// [`std::os::unix::net::UnixDatagram`]: std::os::unix::net::UnixDatagram
/// [`set_nonblocking`]: fn@std::os::unix::net::UnixDatagram::set_nonblocking
pub fn into_std(self) -> io::Result<std::os::unix::net::UnixDatagram> {
self.io
.into_inner()
.map(|io| io.into_raw_fd())
.map(|raw_fd| unsafe { std::os::unix::net::UnixDatagram::from_raw_fd(raw_fd) })
}

fn new(socket: mio::net::UnixDatagram) -> io::Result<UnixDatagram> {
let io = PollEvented::new(socket)?;
Ok(UnixDatagram { io })
Expand Down
31 changes: 30 additions & 1 deletion tokio/src/net/unix/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::net::unix::{SocketAddr, UnixStream};
use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::os::unix::net;
use std::path::Path;
use std::task::{Context, Poll};
Expand Down Expand Up @@ -88,6 +88,35 @@ impl UnixListener {
Ok(UnixListener { io })
}

/// Turn a [`tokio::net::UnixListener`] into a [`std::os::unix::net::UnixListener`].
///
/// The returned [`std::os::unix::net::UnixListener`] will have nonblocking mode
/// set as `true`. Use [`set_nonblocking`] to change the blocking mode if needed.
///
/// # Examples
///
/// ```rust,no_run
/// use std::error::Error;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn Error>> {
/// let tokio_listener = tokio::net::UnixListener::bind("127.0.0.1:0")?;
/// let std_listener = tokio_listener.into_std()?;
/// std_listener.set_nonblocking(false)?;
/// Ok(())
/// }
/// ```
///
/// [`tokio::net::UnixListener`]: UnixListener
/// [`std::os::unix::net::UnixListener`]: std::os::unix::net::UnixListener
/// [`set_nonblocking`]: fn@std::os::unix::net::UnixListener::set_nonblocking
pub fn into_std(self) -> io::Result<std::os::unix::net::UnixListener> {
self.io
.into_inner()
.map(|io| io.into_raw_fd())
.map(|raw_fd| unsafe { net::UnixListener::from_raw_fd(raw_fd) })
}

/// Returns the local socket address of this listener.
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.io.local_addr().map(SocketAddr)
Expand Down
47 changes: 46 additions & 1 deletion tokio/src/net/unix/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::convert::TryFrom;
use std::fmt;
use std::io::{self, Read, Write};
use std::net::Shutdown;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::os::unix::net;
use std::path::Path;
use std::pin::Pin;
Expand Down Expand Up @@ -508,6 +508,51 @@ impl UnixStream {
Ok(UnixStream { io })
}

/// Turn a [`tokio::net::UnixStream`] into a [`std::os::unix::net::UnixStream`].
///
/// The returned [`std::os::unix::net::UnixStream`] will have nonblocking
/// mode set as `true`. Use [`set_nonblocking`] to change the blocking
/// mode if needed.
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::io::Read;
/// use tokio::net::UnixListener;
/// # use tokio::net::UnixStream;
/// # use tokio::io::AsyncWriteExt;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn Error>> {
/// let dir = tempfile::tempdir().unwrap();
/// let bind_path = dir.path().join("bind_path");
///
/// let mut data = [0u8; 12];
/// let listener = UnixListener::bind(&bind_path)?;
/// # let handle = tokio::spawn(async {
/// # let mut stream = UnixStream::connect(bind_path).await.unwrap();
/// # stream.write(b"Hello world!").await.unwrap();
/// # });
/// let (tokio_unix_stream, _) = listener.accept().await?;
/// let mut std_unix_stream = tokio_unix_stream.into_std()?;
/// # handle.await.expect("The task being joined has panicked");
/// std_unix_stream.set_nonblocking(false)?;
/// std_unix_stream.read_exact(&mut data)?;
/// # assert_eq!(b"Hello world!", &data);
/// Ok(())
/// }
/// ```
/// [`tokio::net::UnixStream`]: UnixStream
/// [`std::os::unix::net::UnixStream`]: std::os::unix::net::UnixStream
/// [`set_nonblocking`]: fn@std::os::unix::net::UnixStream::set_nonblocking
pub fn into_std(self) -> io::Result<std::os::unix::net::UnixStream> {
self.io
.into_inner()
.map(|io| io.into_raw_fd())
.map(|raw_fd| unsafe { std::os::unix::net::UnixStream::from_raw_fd(raw_fd) })
}

/// Creates an unnamed pair of connected sockets.
///
/// This function will create a pair of interconnected Unix sockets for
Expand Down

0 comments on commit 58bd242

Please sign in to comment.