about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-01-04 04:28:15 +0000
committerbors <bors@rust-lang.org>2017-01-04 04:28:15 +0000
commit01677eeef2d3536b07dced43d062f4e486fe695c (patch)
tree254a5c725fd5e0380175dd8746abb0f491748d20 /src/libstd
parenta68622c899883b9871b71d5ed600166e2254d230 (diff)
parentc6858a1429895f27b4daafde9295deb494e2e29c (diff)
downloadrust-01677eeef2d3536b07dced43d062f4e486fe695c.tar.gz
rust-01677eeef2d3536b07dced43d062f4e486fe695c.zip
Auto merge of #38707 - redox-os:master, r=brson
Add socket timeout and ttl support in `sys::redox`

This adds support for `read_timeout`, `write_timeout`, and `ttl` on `TcpStream`, `TcpListener`, and `UdpSocket` in the `sys::redox` module.

The DNS lookup has been set to use a 5 second timeout by default.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sys/redox/net/mod.rs4
-rw-r--r--src/libstd/sys/redox/net/tcp.rs75
-rw-r--r--src/libstd/sys/redox/net/udp.rs56
-rw-r--r--src/libstd/sys/redox/syscall/data.rs19
4 files changed, 128 insertions, 26 deletions
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<LookupHost> {
         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<u32> {
-        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<Option<Duration>> {
-        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::<TimeSpec>() {
+            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
+        } else {
+            Ok(None)
+        }
     }
 
     pub fn write_timeout(&self) -> Result<Option<Duration>> {
-        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::<TimeSpec>() {
+            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_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented"))
-    }
-
-    pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout 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, duration_option: Option<Duration>) -> 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, duration_option: Option<Duration>) -> 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<u32> {
-        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<u32> {
-        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<Option<Duration>> {
-        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::<TimeSpec>() {
+            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
+        } else {
+            Ok(None)
+        }
     }
 
     pub fn write_timeout(&self) -> Result<Option<Duration>> {
-        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::<TimeSpec>() {
+            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<Duration>) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_read_timeout not implemented"))
+    pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> 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<Duration>) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_write_timeout not implemented"))
+    pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> 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::<TimeSpec>()) 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::<TimeSpec>()) as &mut [u8]
+        }
+    }
+}