diff --git a/src/librustc_back/target/redox_base.rs b/src/librustc_back/target/redox_base.rs index 1dffff59809..c5e1e107753 100644 --- a/src/librustc_back/target/redox_base.rs +++ b/src/librustc_back/target/redox_base.rs @@ -25,14 +25,7 @@ pub fn opts() -> TargetOptions { "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - - // Static link - "-static".to_string() - ], - late_link_args: vec![ - "-lc".to_string(), - "-lm".to_string() + "-Wl,-z,noexecstack".to_string() ], executables: true, relocation_model: "static".to_string(), @@ -40,7 +33,6 @@ pub fn opts() -> TargetOptions { eliminate_frame_pointer: false, target_family: None, linker_is_gnu: true, - no_default_libraries: true, lib_allocation_crate: "alloc_system".to_string(), exe_allocation_crate: "alloc_system".to_string(), has_elf_tls: true, diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs index 3fdf61cfed8..0291d7f0e92 100644 --- a/src/libstd/sys/redox/net/mod.rs +++ b/src/libstd/sys/redox/net/mod.rs @@ -15,7 +15,7 @@ use net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use str::FromStr; use string::{String, ToString}; use sys::syscall::EINVAL; -use time; +use time::{self, Duration}; use vec::{IntoIter, Vec}; use self::dns::{Dns, DnsQuery}; @@ -69,6 +69,8 @@ pub fn lookup_host(host: &str) -> Result { let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]); let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]); let socket = UdpSocket::bind(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0)))?; + socket.set_read_timeout(Some(Duration::new(5, 0)))?; + socket.set_write_timeout(Some(Duration::new(5, 0)))?; socket.connect(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53)))?; socket.send(&packet_data)?; diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index d5362c9f131..a3f202ccd97 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use cmp; use io::{Error, ErrorKind, Result}; +use mem; use net::{SocketAddr, Shutdown}; use path::Path; use sys::fs::{File, OpenOptions}; +use sys::syscall::TimeSpec; use sys_common::{AsInner, FromInner, IntoInner}; use time::Duration; use vec::Vec; @@ -77,15 +80,30 @@ impl TcpStream { } pub fn ttl(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::ttl not implemented")) + let mut ttl = [0]; + let file = self.0.dup(b"ttl")?; + file.read(&mut ttl)?; + Ok(ttl[0] as u32) } pub fn read_timeout(&self) -> Result> { - Err(Error::new(ErrorKind::Other, "TcpStream::read_timeout not implemented")) + let mut time = TimeSpec::default(); + let file = self.0.dup(b"read_timeout")?; + if file.read(&mut time)? >= mem::size_of::() { + Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) + } else { + Ok(None) + } } pub fn write_timeout(&self) -> Result> { - Err(Error::new(ErrorKind::Other, "TcpStream::write_timeout not implemented")) + let mut time = TimeSpec::default(); + let file = self.0.dup(b"write_timeout")?; + if file.read(&mut time)? >= mem::size_of::() { + Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) + } else { + Ok(None) + } } pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> { @@ -100,16 +118,36 @@ impl TcpStream { Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented")) } - pub fn set_ttl(&self, _ttl: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_ttl not implemented")) + pub fn set_ttl(&self, ttl: u32) -> Result<()> { + let file = self.0.dup(b"ttl")?; + file.write(&[cmp::min(ttl, 255) as u8])?; + Ok(()) } - pub fn set_read_timeout(&self, _dur: Option) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented")) + pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { + let file = self.0.dup(b"read_timeout")?; + if let Some(duration) = duration_option { + file.write(&TimeSpec { + tv_sec: duration.as_secs() as i64, + tv_nsec: duration.subsec_nanos() as i32 + })?; + } else { + file.write(&[])?; + } + Ok(()) } - pub fn set_write_timeout(&self, _dur: Option) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout not implemented")) + pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { + let file = self.0.dup(b"write_timeout")?; + if let Some(duration) = duration_option { + file.write(&TimeSpec { + tv_sec: duration.as_secs() as i64, + tv_nsec: duration.subsec_nanos() as i32 + })?; + } else { + file.write(&[])?; + } + Ok(()) } } @@ -168,7 +206,10 @@ impl TcpListener { } pub fn ttl(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpListener::ttl not implemented")) + let mut ttl = [0]; + let file = self.0.dup(b"ttl")?; + file.read(&mut ttl)?; + Ok(ttl[0] as u32) } pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> { @@ -179,8 +220,10 @@ impl TcpListener { Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented")) } - pub fn set_ttl(&self, _ttl: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpListener::set_ttl not implemented")) + pub fn set_ttl(&self, ttl: u32) -> Result<()> { + let file = self.0.dup(b"ttl")?; + file.write(&[cmp::min(ttl, 255) as u8])?; + Ok(()) } } diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs index 607c66c2ba7..36f0819d308 100644 --- a/src/libstd/sys/redox/net/udp.rs +++ b/src/libstd/sys/redox/net/udp.rs @@ -9,10 +9,13 @@ // except according to those terms. use cell::UnsafeCell; +use cmp; use io::{Error, ErrorKind, Result}; +use mem; use net::{SocketAddr, Ipv4Addr, Ipv6Addr}; use path::Path; use sys::fs::{File, OpenOptions}; +use sys::syscall::TimeSpec; use sys_common::{AsInner, FromInner, IntoInner}; use time::Duration; @@ -109,15 +112,30 @@ impl UdpSocket { } pub fn ttl(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::ttl not implemented")) + let mut ttl = [0]; + let file = self.0.dup(b"ttl")?; + file.read(&mut ttl)?; + Ok(ttl[0] as u32) } pub fn read_timeout(&self) -> Result> { - Err(Error::new(ErrorKind::Other, "UdpSocket::read_timeout not implemented")) + let mut time = TimeSpec::default(); + let file = self.0.dup(b"read_timeout")?; + if file.read(&mut time)? >= mem::size_of::() { + Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) + } else { + Ok(None) + } } pub fn write_timeout(&self) -> Result> { - Err(Error::new(ErrorKind::Other, "UdpSocket::write_timeout not implemented")) + let mut time = TimeSpec::default(); + let file = self.0.dup(b"write_timeout")?; + if file.read(&mut time)? >= mem::size_of::() { + Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) + } else { + Ok(None) + } } pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> { @@ -144,16 +162,36 @@ impl UdpSocket { Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented")) } - pub fn set_ttl(&self, _ttl: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_ttl not implemented")) + pub fn set_ttl(&self, ttl: u32) -> Result<()> { + let file = self.0.dup(b"ttl")?; + file.write(&[cmp::min(ttl, 255) as u8])?; + Ok(()) } - pub fn set_read_timeout(&self, _dur: Option) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_read_timeout not implemented")) + pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { + let file = self.0.dup(b"read_timeout")?; + if let Some(duration) = duration_option { + file.write(&TimeSpec { + tv_sec: duration.as_secs() as i64, + tv_nsec: duration.subsec_nanos() as i32 + })?; + } else { + file.write(&[])?; + } + Ok(()) } - pub fn set_write_timeout(&self, _dur: Option) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_write_timeout not implemented")) + pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { + let file = self.0.dup(b"write_timeout")?; + if let Some(duration) = duration_option { + file.write(&TimeSpec { + tv_sec: duration.as_secs() as i64, + tv_nsec: duration.subsec_nanos() as i32 + })?; + } else { + file.write(&[])?; + } + Ok(()) } pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> { diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs index ac3946672a3..a6b0ada72b8 100644 --- a/src/libstd/sys/redox/syscall/data.rs +++ b/src/libstd/sys/redox/syscall/data.rs @@ -84,3 +84,22 @@ pub struct TimeSpec { pub tv_sec: i64, pub tv_nsec: i32, } + +impl Deref for TimeSpec { + type Target = [u8]; + fn deref(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const TimeSpec as *const u8, + mem::size_of::()) as &[u8] + } + } +} + +impl DerefMut for TimeSpec { + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, + mem::size_of::()) as &mut [u8] + } + } +}