diff --git a/src/tcp/listener.rs b/src/tcp/listener.rs index 73404ae6..cf222169 100644 --- a/src/tcp/listener.rs +++ b/src/tcp/listener.rs @@ -1,5 +1,6 @@ use super::TcpStream; +use std::convert::TryFrom; use std::fmt; use std::io; use std::net::{self, SocketAddr}; @@ -243,6 +244,14 @@ mod sys { } } +impl TryFrom for TcpListener { + type Error = io::Error; + + fn try_from(socket: std::net::TcpListener) -> Result { + mio::net::TcpListener::from_std(socket).map(TcpListener::new) + } +} + /// Stream returned by the `TcpListener::incoming` function representing the /// stream of sockets received from a listener. #[must_use = "streams do nothing unless polled"] diff --git a/src/udp.rs b/src/udp.rs index 6fd428f6..6c892552 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -11,6 +11,7 @@ //! [received from]: #method.poll_recv_from //! [sent to]: #method.poll_send_to +use std::convert::TryFrom; use std::fmt; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; @@ -402,6 +403,14 @@ mod sys { } } +impl TryFrom for UdpSocket { + type Error = io::Error; + + fn try_from(socket: std::net::UdpSocket) -> Result { + mio::net::UdpSocket::from_socket(socket).map(UdpSocket::new) + } +} + /// The future returned by `UdpSocket::send_to` #[derive(Debug)] pub struct SendTo<'a, 'b> { diff --git a/src/uds/ucred.rs b/src/uds/ucred.rs index de127b17..b17ef41e 100644 --- a/src/uds/ucred.rs +++ b/src/uds/ucred.rs @@ -86,12 +86,14 @@ pub(crate) mod impl_macos { unsafe { let raw_fd = sock.as_raw_fd(); - let mut cred: super::UCred = mem::uninitialized(); - - let ret = getpeereid(raw_fd, &mut cred.uid, &mut cred.gid); + let mut cred = mem::MaybeUninit::::uninit(); + let ret = { + let cred_mut = cred.as_mut_ptr(); + getpeereid(raw_fd, &mut (*cred_mut).uid, &mut (*cred_mut).gid) + }; if ret == 0 { - Ok(cred) + Ok(cred.assume_init()) } else { Err(io::Error::last_os_error()) } diff --git a/tests/tcp.rs b/tests/tcp.rs index fc5ff6c4..5fb6dc0a 100644 --- a/tests/tcp.rs +++ b/tests/tcp.rs @@ -1,6 +1,7 @@ #![feature(async_await)] +use std::convert::TryFrom; use std::io::{Read, Write}; -use std::net::TcpStream; +use std::net::{SocketAddr, TcpStream}; use std::thread; use futures::executor; @@ -79,3 +80,11 @@ fn both_sides_async_using_threadpool() { assert_eq!(buf, THE_WINTERS_TALE); })); } + +#[test] +fn listener_from_std() { + drop(env_logger::try_init()); + let addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); + let std_socket = std::net::TcpListener::bind(&addr).unwrap(); + let _ = TcpListener::try_from(std_socket).unwrap(); +} diff --git a/tests/udp.rs b/tests/udp.rs new file mode 100644 index 00000000..916cb43a --- /dev/null +++ b/tests/udp.rs @@ -0,0 +1,38 @@ +#![feature(async_await)] +use std::convert::TryFrom; +use std::net::SocketAddr; +use futures::executor; +use romio::UdpSocket; + +const THE_WINTERS_TALE: &[u8] = b" + Each your doing, + So singular in each particular, + Crowns what you are doing in the present deed, + That all your acts are queens. +"; + +async fn exchange(mut socket: UdpSocket) { + let addr = socket.local_addr().unwrap(); + let mut buf = vec![0; THE_WINTERS_TALE.len()]; + + socket.send_to(THE_WINTERS_TALE, &addr).await.unwrap(); + let (n, sender) = socket.recv_from(&mut buf).await.unwrap(); + assert_eq!(sender, addr); + assert_eq!(&buf[..n], THE_WINTERS_TALE); +} + +#[test] +fn socket_sends_and_receives() { + drop(env_logger::try_init()); + let socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap()).unwrap(); + executor::block_on(exchange(socket)); +} + +#[test] +fn socket_from_std() { + drop(env_logger::try_init()); + let addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); + let std_socket = std::net::UdpSocket::bind(&addr).unwrap(); + let socket = UdpSocket::try_from(std_socket).unwrap(); + executor::block_on(exchange(socket)); +} \ No newline at end of file