Skip to content

Commit 01677ee

Browse files
committed
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.
2 parents a68622c + c6858a1 commit 01677ee

File tree

5 files changed

+129
-35
lines changed

5 files changed

+129
-35
lines changed

src/librustc_back/target/redox_base.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,14 @@ pub fn opts() -> TargetOptions {
2525
"-Wl,--as-needed".to_string(),
2626

2727
// Always enable NX protection when it is available
28-
"-Wl,-z,noexecstack".to_string(),
29-
30-
// Static link
31-
"-static".to_string()
32-
],
33-
late_link_args: vec![
34-
"-lc".to_string(),
35-
"-lm".to_string()
28+
"-Wl,-z,noexecstack".to_string()
3629
],
3730
executables: true,
3831
relocation_model: "static".to_string(),
3932
disable_redzone: true,
4033
eliminate_frame_pointer: false,
4134
target_family: None,
4235
linker_is_gnu: true,
43-
no_default_libraries: true,
4436
lib_allocation_crate: "alloc_system".to_string(),
4537
exe_allocation_crate: "alloc_system".to_string(),
4638
has_elf_tls: true,

src/libstd/sys/redox/net/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use net::{Ipv4Addr, SocketAddr, SocketAddrV4};
1515
use str::FromStr;
1616
use string::{String, ToString};
1717
use sys::syscall::EINVAL;
18-
use time;
18+
use time::{self, Duration};
1919
use vec::{IntoIter, Vec};
2020

2121
use self::dns::{Dns, DnsQuery};
@@ -69,6 +69,8 @@ pub fn lookup_host(host: &str) -> Result<LookupHost> {
6969
let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
7070
let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
7171
let socket = UdpSocket::bind(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0)))?;
72+
socket.set_read_timeout(Some(Duration::new(5, 0)))?;
73+
socket.set_write_timeout(Some(Duration::new(5, 0)))?;
7274
socket.connect(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53)))?;
7375
socket.send(&packet_data)?;
7476

src/libstd/sys/redox/net/tcp.rs

+59-16
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use cmp;
1112
use io::{Error, ErrorKind, Result};
13+
use mem;
1214
use net::{SocketAddr, Shutdown};
1315
use path::Path;
1416
use sys::fs::{File, OpenOptions};
17+
use sys::syscall::TimeSpec;
1518
use sys_common::{AsInner, FromInner, IntoInner};
1619
use time::Duration;
1720
use vec::Vec;
@@ -77,15 +80,30 @@ impl TcpStream {
7780
}
7881

7982
pub fn ttl(&self) -> Result<u32> {
80-
Err(Error::new(ErrorKind::Other, "TcpStream::ttl not implemented"))
83+
let mut ttl = [0];
84+
let file = self.0.dup(b"ttl")?;
85+
file.read(&mut ttl)?;
86+
Ok(ttl[0] as u32)
8187
}
8288

8389
pub fn read_timeout(&self) -> Result<Option<Duration>> {
84-
Err(Error::new(ErrorKind::Other, "TcpStream::read_timeout not implemented"))
90+
let mut time = TimeSpec::default();
91+
let file = self.0.dup(b"read_timeout")?;
92+
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
93+
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
94+
} else {
95+
Ok(None)
96+
}
8597
}
8698

8799
pub fn write_timeout(&self) -> Result<Option<Duration>> {
88-
Err(Error::new(ErrorKind::Other, "TcpStream::write_timeout not implemented"))
100+
let mut time = TimeSpec::default();
101+
let file = self.0.dup(b"write_timeout")?;
102+
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
103+
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
104+
} else {
105+
Ok(None)
106+
}
89107
}
90108

91109
pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> {
@@ -100,16 +118,36 @@ impl TcpStream {
100118
Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
101119
}
102120

103-
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
104-
Err(Error::new(ErrorKind::Other, "TcpStream::set_ttl not implemented"))
105-
}
106-
107-
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
108-
Err(Error::new(ErrorKind::Other, "TcpStream::set_read_timeout not implemented"))
109-
}
110-
111-
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
112-
Err(Error::new(ErrorKind::Other, "TcpStream::set_write_timeout not implemented"))
121+
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
122+
let file = self.0.dup(b"ttl")?;
123+
file.write(&[cmp::min(ttl, 255) as u8])?;
124+
Ok(())
125+
}
126+
127+
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
128+
let file = self.0.dup(b"read_timeout")?;
129+
if let Some(duration) = duration_option {
130+
file.write(&TimeSpec {
131+
tv_sec: duration.as_secs() as i64,
132+
tv_nsec: duration.subsec_nanos() as i32
133+
})?;
134+
} else {
135+
file.write(&[])?;
136+
}
137+
Ok(())
138+
}
139+
140+
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
141+
let file = self.0.dup(b"write_timeout")?;
142+
if let Some(duration) = duration_option {
143+
file.write(&TimeSpec {
144+
tv_sec: duration.as_secs() as i64,
145+
tv_nsec: duration.subsec_nanos() as i32
146+
})?;
147+
} else {
148+
file.write(&[])?;
149+
}
150+
Ok(())
113151
}
114152
}
115153

@@ -168,7 +206,10 @@ impl TcpListener {
168206
}
169207

170208
pub fn ttl(&self) -> Result<u32> {
171-
Err(Error::new(ErrorKind::Other, "TcpListener::ttl not implemented"))
209+
let mut ttl = [0];
210+
let file = self.0.dup(b"ttl")?;
211+
file.read(&mut ttl)?;
212+
Ok(ttl[0] as u32)
172213
}
173214

174215
pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> {
@@ -179,8 +220,10 @@ impl TcpListener {
179220
Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
180221
}
181222

182-
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
183-
Err(Error::new(ErrorKind::Other, "TcpListener::set_ttl not implemented"))
223+
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
224+
let file = self.0.dup(b"ttl")?;
225+
file.write(&[cmp::min(ttl, 255) as u8])?;
226+
Ok(())
184227
}
185228
}
186229

src/libstd/sys/redox/net/udp.rs

+47-9
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
// except according to those terms.
1010

1111
use cell::UnsafeCell;
12+
use cmp;
1213
use io::{Error, ErrorKind, Result};
14+
use mem;
1315
use net::{SocketAddr, Ipv4Addr, Ipv6Addr};
1416
use path::Path;
1517
use sys::fs::{File, OpenOptions};
18+
use sys::syscall::TimeSpec;
1619
use sys_common::{AsInner, FromInner, IntoInner};
1720
use time::Duration;
1821

@@ -109,15 +112,30 @@ impl UdpSocket {
109112
}
110113

111114
pub fn ttl(&self) -> Result<u32> {
112-
Err(Error::new(ErrorKind::Other, "UdpSocket::ttl not implemented"))
115+
let mut ttl = [0];
116+
let file = self.0.dup(b"ttl")?;
117+
file.read(&mut ttl)?;
118+
Ok(ttl[0] as u32)
113119
}
114120

115121
pub fn read_timeout(&self) -> Result<Option<Duration>> {
116-
Err(Error::new(ErrorKind::Other, "UdpSocket::read_timeout not implemented"))
122+
let mut time = TimeSpec::default();
123+
let file = self.0.dup(b"read_timeout")?;
124+
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
125+
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
126+
} else {
127+
Ok(None)
128+
}
117129
}
118130

119131
pub fn write_timeout(&self) -> Result<Option<Duration>> {
120-
Err(Error::new(ErrorKind::Other, "UdpSocket::write_timeout not implemented"))
132+
let mut time = TimeSpec::default();
133+
let file = self.0.dup(b"write_timeout")?;
134+
if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
135+
Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
136+
} else {
137+
Ok(None)
138+
}
121139
}
122140

123141
pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> {
@@ -144,16 +162,36 @@ impl UdpSocket {
144162
Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented"))
145163
}
146164

147-
pub fn set_ttl(&self, _ttl: u32) -> Result<()> {
148-
Err(Error::new(ErrorKind::Other, "UdpSocket::set_ttl not implemented"))
165+
pub fn set_ttl(&self, ttl: u32) -> Result<()> {
166+
let file = self.0.dup(b"ttl")?;
167+
file.write(&[cmp::min(ttl, 255) as u8])?;
168+
Ok(())
149169
}
150170

151-
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> Result<()> {
152-
Err(Error::new(ErrorKind::Other, "UdpSocket::set_read_timeout not implemented"))
171+
pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
172+
let file = self.0.dup(b"read_timeout")?;
173+
if let Some(duration) = duration_option {
174+
file.write(&TimeSpec {
175+
tv_sec: duration.as_secs() as i64,
176+
tv_nsec: duration.subsec_nanos() as i32
177+
})?;
178+
} else {
179+
file.write(&[])?;
180+
}
181+
Ok(())
153182
}
154183

155-
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> Result<()> {
156-
Err(Error::new(ErrorKind::Other, "UdpSocket::set_write_timeout not implemented"))
184+
pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
185+
let file = self.0.dup(b"write_timeout")?;
186+
if let Some(duration) = duration_option {
187+
file.write(&TimeSpec {
188+
tv_sec: duration.as_secs() as i64,
189+
tv_nsec: duration.subsec_nanos() as i32
190+
})?;
191+
} else {
192+
file.write(&[])?;
193+
}
194+
Ok(())
157195
}
158196

159197
pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> {

src/libstd/sys/redox/syscall/data.rs

+19
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,22 @@ pub struct TimeSpec {
8484
pub tv_sec: i64,
8585
pub tv_nsec: i32,
8686
}
87+
88+
impl Deref for TimeSpec {
89+
type Target = [u8];
90+
fn deref(&self) -> &[u8] {
91+
unsafe {
92+
slice::from_raw_parts(self as *const TimeSpec as *const u8,
93+
mem::size_of::<TimeSpec>()) as &[u8]
94+
}
95+
}
96+
}
97+
98+
impl DerefMut for TimeSpec {
99+
fn deref_mut(&mut self) -> &mut [u8] {
100+
unsafe {
101+
slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8,
102+
mem::size_of::<TimeSpec>()) as &mut [u8]
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)