Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port to wasm32-wasi #1395

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ miow = "0.3.3"
winapi = { version = "0.3", features = ["winsock2", "mswsock"] }
ntapi = "0.3"

[target.'cfg(target_os = "wasi")'.dependencies]
wasi = "0.10.0+wasi-snapshot-preview1"

[dev-dependencies]
env_logger = { version = "0.6.2", default-features = false }
rand = "0.4"
Expand Down
36 changes: 36 additions & 0 deletions src/io_source.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::ops::{Deref, DerefMut};
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
#[cfg(target_os = "wasi")]
use std::os::wasi::io::AsRawFd;
#[cfg(windows)]
use std::os::windows::io::AsRawSocket;
#[cfg(debug_assertions)]
Expand Down Expand Up @@ -198,6 +200,40 @@ where
}
}

#[cfg(target_os = "wasi")]
impl<T> event::Source for IoSource<T>
where
T: AsRawFd,
{
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.associate(registry)?;
poll::selector(registry).register(self.inner.as_raw_fd(), token, interests)
}

fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.check_association(registry)?;
poll::selector(registry).reregister(self.inner.as_raw_fd(), token, interests)
}

fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.remove_association(registry)?;
poll::selector(registry).deregister(self.inner.as_raw_fd())
}
}

impl<T> fmt::Debug for IoSource<T>
where
T: fmt::Debug,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
//!
//! The available features are described in the [`features`] module.

#![feature(wasi_ext)]

// macros used internally
#[macro_use]
mod macros;
Expand Down
29 changes: 29 additions & 0 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::net::{self, SocketAddr};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
use std::{fmt, io};
Expand Down Expand Up @@ -206,3 +208,30 @@ impl FromRawSocket for TcpListener {
TcpListener::from_std(FromRawSocket::from_raw_socket(socket))
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for TcpListener {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl AsRawFd for TcpListener {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl FromRawFd for TcpListener {
/// Converts a `RawFd` to a `TcpListener`.
///
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
TcpListener::from_std(FromRawFd::from_raw_fd(fd))
}
}
65 changes: 53 additions & 12 deletions src/net/tcp/socket.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use crate::net::{TcpStream, TcpListener};
use crate::sys;

use std::io;
use std::mem;
use std::net::SocketAddr;
use std::time::Duration;

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};

use crate::net::{TcpListener, TcpStream};
use crate::sys;

/// A non-blocking TCP socket used to configure a stream or listener.
///
/// The `TcpSocket` type wraps the operating-system's socket handle. This type
Expand All @@ -27,18 +30,14 @@ impl TcpSocket {
///
/// This calls `socket(2)`.
pub fn new_v4() -> io::Result<TcpSocket> {
sys::tcp::new_v4_socket().map(|sys| TcpSocket {
sys
})
sys::tcp::new_v4_socket().map(|sys| TcpSocket { sys })
}

/// Create a new IPv6 TCP socket.
///
/// This calls `socket(2)`.
pub fn new_v6() -> io::Result<TcpSocket> {
sys::tcp::new_v6_socket().map(|sys| TcpSocket {
sys
})
sys::tcp::new_v6_socket().map(|sys| TcpSocket { sys })
}

pub(crate) fn new_for_addr(addr: SocketAddr) -> io::Result<TcpSocket> {
Expand Down Expand Up @@ -168,7 +167,7 @@ impl TcpSocket {
pub fn get_send_buffer_size(&self) -> io::Result<u32> {
sys::tcp::get_send_buffer_size(self.sys)
}

/// Returns the local address of this socket
///
/// Will return `Err` result in windows if called before calling `bind`
Expand All @@ -183,6 +182,16 @@ impl Drop for TcpSocket {
}
}

#[cfg(unix)]
impl IntoRawFd for TcpSocket {
fn into_raw_fd(self) -> RawFd {
let ret = self.sys;
// Avoid closing the socket
mem::forget(self);
ret
}
}

#[cfg(unix)]
impl AsRawFd for TcpSocket {
fn as_raw_fd(&self) -> RawFd {
Expand Down Expand Up @@ -235,6 +244,38 @@ impl FromRawSocket for TcpSocket {
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
TcpSocket { sys: socket as sys::tcp::TcpSocket }
TcpSocket {
sys: socket as sys::tcp::TcpSocket,
}
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for TcpSocket {
fn into_raw_fd(self) -> RawFd {
let ret = self.sys;
// Avoid closing the socket
mem::forget(self);
ret
}
}

#[cfg(target_os = "wasi")]
impl AsRawFd for TcpSocket {
fn as_raw_fd(&self) -> RawFd {
self.sys
}
}

#[cfg(target_os = "wasi")]
impl FromRawFd for TcpSocket {
/// Converts a `RawFd` to a `TcpSocket`.
///
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
TcpSocket { sys: fd }
}
}
31 changes: 30 additions & 1 deletion src/net/tcp/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use std::io::{self, IoSlice, IoSliceMut, Read, Write};
use std::net::{self, Shutdown, SocketAddr};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};

use crate::io_source::IoSource;
use crate::{event, Interest, Registry, Token};
use crate::net::TcpSocket;
use crate::{event, Interest, Registry, Token};

/// A non-blocking TCP stream between a local socket and a remote socket.
///
Expand Down Expand Up @@ -302,3 +304,30 @@ impl FromRawSocket for TcpStream {
TcpStream::from_std(FromRawSocket::from_raw_socket(socket))
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for TcpStream {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl AsRawFd for TcpStream {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl FromRawFd for TcpStream {
/// Converts a `RawFd` to a `TcpStream`.
///
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
TcpStream::from_std(FromRawFd::from_raw_fd(fd))
}
}
29 changes: 29 additions & 0 deletions src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use std::net;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};

Expand Down Expand Up @@ -595,3 +597,30 @@ impl FromRawSocket for UdpSocket {
UdpSocket::from_std(FromRawSocket::from_raw_socket(socket))
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for UdpSocket {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}

#[cfg(target_os = "wasi")]
impl FromRawFd for UdpSocket {
/// Converts a `RawFd` to a `UdpSocket`.
///
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
UdpSocket::from_std(FromRawFd::from_raw_fd(fd))
}
}
6 changes: 6 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ cfg_os_poll! {
pub use self::windows::*;
}

#[cfg(target_os = "wasi")]
cfg_os_poll! {
mod wasi;
pub(crate) use self::wasi::*;
}

cfg_not_os_poll! {
mod shell;
pub(crate) use self::shell::*;
Expand Down
Loading