Skip to content

Commit

Permalink
Merge-in build fixes (#96, branch euclio:untry).
Browse files Browse the repository at this point in the history
  • Loading branch information
Jozef Hatala committed Mar 9, 2020
2 parents a87d94a + fd42fb7 commit ac31812
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 79 deletions.
11 changes: 9 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: rust
sudo: false
sudo: required

matrix:
include:
Expand All @@ -10,7 +10,7 @@ matrix:
- rust: nightly
script:
- cargo test
- cargo test --feature snightly
- cargo test --features nightly

- rust: nightly
before_script:
Expand All @@ -20,6 +20,13 @@ matrix:
after_success:
- travis-cargo doc-upload

before_script:
# Add an IPv6 config - see the corresponding Travis issue
# https://github.com/travis-ci/travis-ci/issues/8361
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
fi

script:
- cargo test

Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ Extensions to the standard library's networking types as proposed in RFC 1158.
[target."cfg(windows)".dependencies]
winapi = { version = "0.3", features = ["handleapi", "winsock2", "ws2def", "ws2ipdef", "ws2tcpip"] }

[target.'cfg(any(target_os="redox", unix))'.dependencies]
libc = "0.2.42"
[target.'cfg(any(target_os="redox", unix, target_os="wasi"))'.dependencies]
libc = "0.2.54"

[dependencies]
cfg-if = "0.1"
cfg-if = "<0.1.10"

[features]
nightly = []
Expand Down
170 changes: 118 additions & 52 deletions src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ cfg_if! {

use std::time::Duration;

#[cfg(any(unix, target_os = "redox"))] use libc::*;
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] use libc::*;
#[cfg(any(unix, target_os = "redox"))] use std::os::unix::prelude::*;
#[cfg(target_os = "wasi")] use std::os::wasi::prelude::*;
#[cfg(target_os = "redox")] pub type Socket = usize;
#[cfg(unix)] pub type Socket = c_int;
#[cfg(target_os = "wasi")] pub type Socket = std::os::wasi::io::RawFd;
#[cfg(windows)] pub type Socket = SOCKET;
#[cfg(windows)] use std::os::windows::prelude::*;
#[cfg(windows)] use sys::c::*;
#[cfg(any(windows, target_os = "wasi"))] use sys::c::*;

#[cfg(windows)] const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
#[cfg(windows)]
Expand All @@ -55,31 +57,42 @@ struct tcp_keepalive {
keepaliveinterval: c_ulong,
}

#[cfg(target_os = "redox")] fn v(opt: c_int) -> c_int { opt }
#[cfg(unix)] fn v(opt: c_int) -> c_int { opt }
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] fn v(opt: c_int) -> c_int { opt }
#[cfg(windows)] fn v(opt: IPPROTO) -> c_int { opt as c_int }

#[cfg(target_os = "wasi")]
pub fn set_opt<T: Copy>(_sock: Socket, _opt: c_int, _val: c_int,
_payload: T) -> io::Result<()> {
Ok(())
}

#[cfg(not(target_os = "wasi"))]
pub fn set_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int,
payload: T) -> io::Result<()> {
unsafe {
let payload = &payload as *const T as *const c_void;
#[cfg(target_os = "redox")]
let sock = sock as c_int;
try!(::cvt(setsockopt(sock, opt, val, payload as *const _,
mem::size_of::<T>() as socklen_t)));
Ok(())
::cvt(setsockopt(sock, opt, val, payload as *const _,
mem::size_of::<T>() as socklen_t))?;
}
Ok(())
}

#[cfg(target_os = "wasi")]
pub fn get_opt<T: Copy>(_sock: Socket, _opt: c_int, _val: c_int) -> io::Result<T> {
unimplemented!()
}
#[cfg(not(target_os = "wasi"))]
pub fn get_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int) -> io::Result<T> {
unsafe {
let mut slot: T = mem::zeroed();
let mut len = mem::size_of::<T>() as socklen_t;
#[cfg(target_os = "redox")]
let sock = sock as c_int;
try!(::cvt(getsockopt(sock, opt, val,
::cvt(getsockopt(sock, opt, val,
&mut slot as *mut _ as *mut _,
&mut len)));
&mut len))?;
assert_eq!(len as usize, mem::size_of::<T>());
Ok(slot)
}
Expand Down Expand Up @@ -641,11 +654,7 @@ pub trait AsSock {
fn as_sock(&self) -> Socket;
}

#[cfg(target_os = "redox")]
impl<T: AsRawFd> AsSock for T {
fn as_sock(&self) -> Socket { self.as_raw_fd() }
}
#[cfg(unix)]
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
impl<T: AsRawFd> AsSock for T {
fn as_sock(&self) -> Socket { self.as_raw_fd() }
}
Expand Down Expand Up @@ -707,58 +716,76 @@ impl TcpStreamExt for TcpStream {

#[cfg(target_os = "redox")]
fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
try!(set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
keepalive.is_some() as c_int));
set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
keepalive.is_some() as c_int)?;
if let Some(dur) = keepalive {
try!(set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
(dur / 1000) as c_int));
set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
(dur / 1000) as c_int)?;
}
Ok(())
}

#[cfg(target_os = "redox")]
fn keepalive_ms(&self) -> io::Result<Option<u32>> {
let keepalive = try!(get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
SO_KEEPALIVE));
let keepalive = get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
SO_KEEPALIVE)?;
if keepalive == 0 {
return Ok(None)
}
let secs = try!(get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
KEEPALIVE_OPTION));
let secs = get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
KEEPALIVE_OPTION)?;
Ok(Some((secs as u32) * 1000))
}

#[cfg(unix)]
#[cfg(target_os = "openbsd")]
fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
try!(set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
keepalive.is_some() as c_int));
cfg_if! {
if #[cfg(not(target_os = "openbsd"))] {
if let Some(dur) = keepalive {
try!(set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
(dur / 1000) as c_int));
}
}
}
set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
keepalive.is_some() as c_int)?;
Ok(())
}

#[cfg(unix)]
#[cfg(target_os = "openbsd")]
fn keepalive_ms(&self) -> io::Result<Option<u32>> {
let keepalive = try!(get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
SO_KEEPALIVE));
let keepalive = get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
SO_KEEPALIVE)?;
if keepalive == 0 {
return Ok(None)
} else {
return Ok(Some(1u32))
}
cfg_if! {
if #[cfg(target_os = "openbsd")] {
Ok(None)
} else {
let secs = try!(get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
KEEPALIVE_OPTION));
Ok(Some((secs as u32) * 1000))
}
}

#[cfg(all(unix, not(target_os = "openbsd")))]
fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
keepalive.is_some() as c_int)?;
if let Some(dur) = keepalive {
set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
(dur / 1000) as c_int)?;
}
Ok(())
}

#[cfg(all(unix, not(target_os = "openbsd")))]
fn keepalive_ms(&self) -> io::Result<Option<u32>> {
let keepalive = get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
SO_KEEPALIVE)?;
if keepalive == 0 {
return Ok(None)
}
let secs = get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
KEEPALIVE_OPTION)?;
Ok(Some((secs as u32) * 1000))
}

#[cfg(target_os = "wasi")]
fn set_keepalive_ms(&self, _keepalive: Option<u32>) -> io::Result<()> {
unimplemented!()
}

#[cfg(target_os = "wasi")]
fn keepalive_ms(&self) -> io::Result<Option<u32>> {
unimplemented!()
}

#[cfg(windows)]
Expand Down Expand Up @@ -790,15 +817,15 @@ impl TcpStreamExt for TcpStream {
keepaliveinterval: 0,
};
unsafe {
try!(::cvt_win(WSAIoctl(self.as_sock(),
::cvt_win(WSAIoctl(self.as_sock(),
SIO_KEEPALIVE_VALS,
0 as *mut _,
0,
&mut ka as *mut _ as *mut _,
mem::size_of_val(&ka) as DWORD,
0 as *mut _,
0 as *mut _,
None)));
None))?;
}
Ok({
if ka.onoff == 0 {
Expand Down Expand Up @@ -883,7 +910,7 @@ impl TcpStreamExt for TcpStream {
}
}

#[cfg(any(target_os = "redox", unix))]
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
fn ms2timeout(dur: Option<u32>) -> timeval {
// TODO: be more rigorous
match dur {
Expand All @@ -895,7 +922,7 @@ fn ms2timeout(dur: Option<u32>) -> timeval {
}
}

#[cfg(any(target_os = "redox", unix))]
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
fn timeout2ms(dur: timeval) -> Option<u32> {
if dur.tv_sec == 0 && dur.tv_usec == 0 {
None
Expand Down Expand Up @@ -940,7 +967,7 @@ fn dur2linger(dur: Option<Duration>) -> linger {
}
}

#[cfg(any(target_os = "redox", unix))]
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
fn dur2linger(dur: Option<Duration>) -> linger {
match dur {
Some(d) => {
Expand Down Expand Up @@ -1204,6 +1231,22 @@ impl UdpSocketExt for UdpSocket {
}
}

#[cfg(target_os = "wasi")]
fn send(&self, buf: &[u8]) -> io::Result<usize> {
let _so_datalen: *mut sys::c::size_t = &mut 0;
unsafe {
let _errno = libc::__wasi_sock_send(
self.as_sock() as libc::__wasi_fd_t,
buf.as_ptr() as *const _,
buf.len(),
0,
_so_datalen,
);
// TODO: handle errno
Ok((*_so_datalen) as usize)
}
}

#[cfg(windows)]
fn send(&self, buf: &[u8]) -> io::Result<usize> {
let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
Expand All @@ -1230,6 +1273,24 @@ impl UdpSocketExt for UdpSocket {
}
}

#[cfg(target_os = "wasi")]
fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
let _ro_datalen: *mut sys::c::size_t = &mut 0;
let _ro_flags: *mut sys::c::__wasi_roflags_t = &mut 0;
unsafe {
let _errno = __wasi_sock_recv(
self.as_sock(),
buf.as_mut_ptr() as *mut _,
buf.len(),
0,
_ro_datalen,
_ro_flags,
);
// TODO: handle errno
Ok((*_ro_datalen) as usize)
}
}

#[cfg(windows)]
fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
Expand All @@ -1248,7 +1309,7 @@ impl UdpSocketExt for UdpSocket {
fn do_connect<A: ToSocketAddrs>(sock: Socket, addr: A) -> io::Result<()> {
let err = io::Error::new(io::ErrorKind::Other,
"no socket addresses resolved");
let addrs = try!(addr.to_socket_addrs());
let addrs = addr.to_socket_addrs()?;
let sys = sys::Socket::from_inner(sock);
let sock = socket::Socket::from_inner(sys);
let ret = addrs.fold(Err(err), |prev, addr| {
Expand Down Expand Up @@ -1281,6 +1342,11 @@ fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
}).map(|_| ())
}

#[cfg(target_os = "wasi")]
fn set_nonblocking(_sock: Socket, _nonblocking: bool) -> io::Result<()> {
Ok(())
}

#[cfg(windows)]
fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
let mut nonblocking = nonblocking as c_ulong;
Expand All @@ -1300,7 +1366,7 @@ fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
}
}

#[cfg(unix)]
#[cfg(any(unix, target_os = "wasi"))]
fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
let oct = ip.octets();
in_addr {
Expand Down Expand Up @@ -1432,7 +1498,7 @@ impl TcpBuilder {

/// Set value for the `SO_REUSEADDR` option on this socket.
///
/// This indicates that futher calls to `bind` may allow reuse of local
/// This indicates that further calls to `bind` may allow reuse of local
/// addresses. For IPv4 sockets this means that a socket may bind even when
/// there's a socket already listening on this port.
pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@
html_root_url = "https://doc.rust-lang.org/net2-rs")]
#![deny(missing_docs, warnings)]

#![cfg_attr(target_os = "wasi", feature(wasi_ext))]

#[cfg(any(target_os="redox", unix))] extern crate libc;
#[cfg(any(target_os = "redox", target_os = "wasi", unix))] extern crate libc;

#[cfg(windows)] extern crate winapi;

Expand All @@ -63,14 +64,15 @@ mod utils;
#[cfg(target_os="redox")] #[path = "sys/redox/mod.rs"] mod sys;
#[cfg(unix)] #[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)] #[path = "sys/windows/mod.rs"] mod sys;
#[cfg(target_os = "wasi")] #[path = "sys/wasi/mod.rs"] mod sys;
#[cfg(all(unix, not(any(target_os = "solaris"))))] pub mod unix;

pub use tcp::TcpBuilder;
pub use udp::UdpBuilder;
pub use ext::{TcpStreamExt, TcpListenerExt, UdpSocketExt};

fn one_addr<T: ToSocketAddrs>(tsa: T) -> io::Result<SocketAddr> {
let mut addrs = try!(tsa.to_socket_addrs());
let mut addrs = tsa.to_socket_addrs()?;
let addr = match addrs.next() {
Some(addr) => addr,
None => return Err(io::Error::new(io::ErrorKind::Other,
Expand Down

0 comments on commit ac31812

Please sign in to comment.