Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ mod udp;
#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
pub use self::udp::UdpSocket;

#[cfg(unix)]
#[cfg(any(unix, windows))]
mod uds;
#[cfg(unix)]
pub use self::uds::{UnixDatagram, UnixListener, UnixStream};
#[cfg(windows)]
pub use self::uds::{SocketAddr, UnixListener, UnixStream};
95 changes: 92 additions & 3 deletions src/net/uds/listener.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
#[cfg(unix)]
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[cfg(unix)]
use std::os::unix::net::{self, SocketAddr};
#[cfg(windows)]
use std::os::windows::io::{
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
use std::path::Path;
use std::{fmt, io};

use crate::io_source::IoSource;
use crate::net::UnixStream;
use crate::{event, sys, Interest, Registry, Token};
use crate::sys;
#[cfg(windows)]
use crate::sys::uds::{Socket, SocketAddr};
use crate::{event, Interest, Registry, Token};

#[cfg(unix)]
type Inner = net::UnixListener;
#[cfg(windows)]
type Inner = Socket;

/// A non-blocking Unix domain socket server.
pub struct UnixListener {
inner: IoSource<net::UnixListener>,
inner: IoSource<Inner>,
}

impl UnixListener {
Expand All @@ -21,7 +35,19 @@ impl UnixListener {

/// Creates a new `UnixListener` bound to the specified socket `address`.
pub fn bind_addr(address: &SocketAddr) -> io::Result<UnixListener> {
sys::uds::listener::bind_addr(address).map(UnixListener::from_std)
#[cfg(unix)]
{
sys::uds::listener::bind_addr(address).map(UnixListener::from_std)
}

// Once std::os::windows::net::UnixListener is stabilized, this can be removed.
#[cfg(windows)]
{
let socket = sys::uds::listener::bind_addr(address)?;
Ok(UnixListener {
inner: IoSource::new(Socket::from(socket)),
})
}
}

/// Creates a new `UnixListener` from a standard `net::UnixListener`.
Expand All @@ -30,6 +56,7 @@ impl UnixListener {
/// standard library in the Mio equivalent. The conversion assumes nothing
/// about the underlying listener; it is left up to the user to set it in
/// non-blocking mode.
#[cfg(unix)]
pub fn from_std(listener: net::UnixListener) -> UnixListener {
UnixListener {
inner: IoSource::new(listener),
Expand Down Expand Up @@ -85,18 +112,21 @@ impl fmt::Debug for UnixListener {
}
}

#[cfg(unix)]
impl IntoRawFd for UnixListener {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}

#[cfg(unix)]
impl AsRawFd for UnixListener {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}

#[cfg(unix)]
impl FromRawFd for UnixListener {
/// Converts a `RawFd` to a `UnixListener`.
///
Expand All @@ -109,6 +139,7 @@ impl FromRawFd for UnixListener {
}
}

#[cfg(unix)]
impl From<UnixListener> for net::UnixListener {
fn from(listener: UnixListener) -> Self {
// Safety: This is safe since we are extracting the raw fd from a well-constructed
Expand All @@ -118,20 +149,78 @@ impl From<UnixListener> for net::UnixListener {
}
}

#[cfg(unix)]
impl From<UnixListener> for OwnedFd {
fn from(unix_listener: UnixListener) -> Self {
unix_listener.inner.into_inner().into()
}
}

#[cfg(unix)]
impl AsFd for UnixListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(unix)]
impl From<OwnedFd> for UnixListener {
fn from(fd: OwnedFd) -> Self {
UnixListener::from_std(From::from(fd))
}
}

#[cfg(windows)]
impl AsRawSocket for UnixListener {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}

#[cfg(windows)]
impl IntoRawSocket for UnixListener {
fn into_raw_socket(self) -> RawSocket {
self.inner.into_inner().into_raw_socket()
}
}

#[cfg(windows)]
impl FromRawSocket for UnixListener {
/// # Safety
///
/// The socket must be a valid, bound, listening `AF_UNIX` socket in
/// non-blocking mode.
unsafe fn from_raw_socket(sock: RawSocket) -> UnixListener {
UnixListener {
inner: IoSource::new(unsafe { Socket::from_raw_socket(sock) }),
}
}
}

#[cfg(windows)]
impl AsSocket for UnixListener {
fn as_socket(&self) -> BorrowedSocket<'_> {
// SAFETY: the raw socket is valid for the lifetime of `self`.
unsafe { BorrowedSocket::borrow_raw(self.inner.as_raw_socket()) }
}
}

#[cfg(windows)]
impl From<UnixListener> for OwnedSocket {
fn from(listener: UnixListener) -> Self {
listener.inner.into_inner().into()
}
}

#[cfg(windows)]
impl From<OwnedSocket> for UnixListener {
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
fn from(socket: OwnedSocket) -> Self {
UnixListener {
inner: IoSource::new(Socket::from(socket)),
}
}
}
6 changes: 6 additions & 0 deletions src/net/uds/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#[cfg(unix)]
mod datagram;
#[cfg(unix)]
pub use self::datagram::UnixDatagram;

mod listener;
pub use self::listener::UnixListener;

mod stream;
pub use self::stream::UnixStream;

// This is a stand-in until std::os::windows::net::SocketAddr is stabilized.
#[cfg(windows)]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is meant to be temporary, probably shouldn't be mio::net::uds::SocketAddr. Would want to decide on a suitable path that conveys temporariness.

pub use crate::sys::uds::SocketAddr;
Loading