Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1b521f5

Browse files
committedApr 4, 2020
Auto merge of #70136 - hermitcore:network_tcp, r=dtolnay
add basic IP support in HermitCore - add initial version to support sockets - use TcpStream as test case - HermitCore uses smoltcp as IP stack for pure Rust applications - further functionalities (e.g. UDP support) will be added step by step - in principle, the current PR is a revision of #69404
2 parents 6050e52 + 57b7203 commit 1b521f5

File tree

3 files changed

+158
-89
lines changed

3 files changed

+158
-89
lines changed
 

‎Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,9 +1377,9 @@ dependencies = [
13771377

13781378
[[package]]
13791379
name = "hermit-abi"
1380-
version = "0.1.1"
1380+
version = "0.1.8"
13811381
source = "registry+https://github.com/rust-lang/crates.io-index"
1382-
checksum = "f22b8f315b98f415780ddbe9163c7dbbc5a07225b6d102ace1d8aeef85775140"
1382+
checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
13831383
dependencies = [
13841384
"compiler_builtins",
13851385
"libc",

‎src/libstd/sys/hermit/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ pub unsafe extern "C" fn __rust_abort() {
9393

9494
#[cfg(not(test))]
9595
pub fn init() {
96-
unsafe {
97-
let _ = net::init();
98-
}
96+
let _ = net::init();
9997
}
10098

10199
#[cfg(not(test))]

‎src/libstd/sys/hermit/net.rs

Lines changed: 155 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,291 +1,362 @@
11
use crate::convert::TryFrom;
22
use crate::fmt;
3-
use crate::io::{self, IoSlice, IoSliceMut};
3+
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
44
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
55
use crate::str;
6+
use crate::sys::hermit::abi;
67
use crate::sys::{unsupported, Void};
78
use crate::time::Duration;
89

9-
//// Iinitializes HermitCore's network stack
10-
pub unsafe fn init() -> io::Result<()> {
10+
/// Checks whether the HermitCore's socket interface has been started already, and
11+
/// if not, starts it.
12+
pub fn init() -> io::Result<()> {
13+
if abi::network_init() < 0 {
14+
return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface"));
15+
}
16+
1117
Ok(())
1218
}
1319

14-
pub struct TcpStream(Void);
20+
pub struct TcpStream(abi::Handle);
1521

1622
impl TcpStream {
17-
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
18-
unsupported()
23+
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
24+
let addr = addr?;
25+
26+
match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
27+
Ok(handle) => Ok(TcpStream(handle)),
28+
_ => {
29+
Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
30+
}
31+
}
1932
}
2033

21-
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
22-
unsupported()
34+
pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
35+
match abi::tcpstream::connect(
36+
saddr.ip().to_string().as_bytes(),
37+
saddr.port(),
38+
Some(duration.as_millis() as u64),
39+
) {
40+
Ok(handle) => Ok(TcpStream(handle)),
41+
_ => {
42+
Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
43+
}
44+
}
2345
}
2446

25-
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
26-
match self.0 {}
47+
pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
48+
abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64))
49+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
2750
}
2851

29-
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
30-
match self.0 {}
52+
pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
53+
abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64))
54+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
3155
}
3256

3357
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
34-
match self.0 {}
58+
let duration = abi::tcpstream::get_read_timeout(self.0)
59+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
60+
61+
Ok(duration.map(|d| Duration::from_millis(d)))
3562
}
3663

3764
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
38-
match self.0 {}
65+
let duration = abi::tcpstream::get_write_timeout(self.0)
66+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
67+
68+
Ok(duration.map(|d| Duration::from_millis(d)))
3969
}
4070

41-
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
42-
match self.0 {}
71+
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
72+
abi::tcpstream::peek(self.0, buf)
73+
.map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
4374
}
4475

45-
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
46-
match self.0 {}
76+
pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
77+
self.read_vectored(&mut [IoSliceMut::new(buffer)])
4778
}
4879

49-
pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
50-
match self.0 {}
80+
pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
81+
let mut size: usize = 0;
82+
83+
for i in ioslice.iter_mut() {
84+
let mut pos: usize = 0;
85+
86+
while pos < i.len() {
87+
let ret = abi::tcpstream::read(self.0, &mut i[pos..])
88+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?;
89+
90+
if ret == 0 {
91+
return Ok(size);
92+
} else {
93+
size += ret;
94+
pos += ret;
95+
}
96+
}
97+
}
98+
99+
Ok(size)
51100
}
52101

53-
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
54-
match self.0 {}
102+
pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
103+
self.write_vectored(&[IoSlice::new(buffer)])
55104
}
56105

57-
pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
58-
match self.0 {}
106+
pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
107+
let mut size: usize = 0;
108+
109+
for i in ioslice.iter() {
110+
size += abi::tcpstream::write(self.0, i)
111+
.map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?;
112+
}
113+
114+
Ok(size)
59115
}
60116

61117
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
62-
match self.0 {}
118+
Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
63119
}
64120

65121
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
66-
match self.0 {}
122+
Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported"))
67123
}
68124

69-
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
70-
match self.0 {}
125+
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
126+
abi::tcpstream::shutdown(self.0, how as i32)
127+
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket"))
71128
}
72129

73130
pub fn duplicate(&self) -> io::Result<TcpStream> {
74-
match self.0 {}
131+
let handle = abi::tcpstream::duplicate(self.0)
132+
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?;
133+
134+
Ok(TcpStream(handle))
75135
}
76136

77-
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
78-
match self.0 {}
137+
pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
138+
abi::tcpstream::set_nodelay(self.0, mode)
139+
.map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
79140
}
80141

81142
pub fn nodelay(&self) -> io::Result<bool> {
82-
match self.0 {}
143+
abi::tcpstream::nodelay(self.0)
144+
.map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed"))
83145
}
84146

85-
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
86-
match self.0 {}
147+
pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
148+
abi::tcpstream::set_tll(self.0, tll)
149+
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL"))
87150
}
88151

89152
pub fn ttl(&self) -> io::Result<u32> {
90-
match self.0 {}
153+
abi::tcpstream::get_tll(self.0)
154+
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL"))
91155
}
92156

93157
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
94-
match self.0 {}
158+
Err(io::Error::new(ErrorKind::Other, "take_error isn't supported"))
95159
}
96160

97-
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
98-
match self.0 {}
161+
pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
162+
abi::tcpstream::set_nonblocking(self.0, mode)
163+
.map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode"))
164+
}
165+
}
166+
167+
impl Drop for TcpStream {
168+
fn drop(&mut self) {
169+
let _ = abi::tcpstream::close(self.0);
99170
}
100171
}
101172

102173
impl fmt::Debug for TcpStream {
103174
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
104-
match self.0 {}
175+
Ok(())
105176
}
106177
}
107178

108-
pub struct TcpListener(Void);
179+
pub struct TcpListener(abi::Handle);
109180

110181
impl TcpListener {
111182
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
112-
unsupported()
183+
Err(io::Error::new(ErrorKind::Other, "not supported"))
113184
}
114185

115186
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
116-
match self.0 {}
187+
Err(io::Error::new(ErrorKind::Other, "not supported"))
117188
}
118189

119190
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
120-
match self.0 {}
191+
Err(io::Error::new(ErrorKind::Other, "not supported"))
121192
}
122193

123194
pub fn duplicate(&self) -> io::Result<TcpListener> {
124-
match self.0 {}
195+
Err(io::Error::new(ErrorKind::Other, "not supported"))
125196
}
126197

127198
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
128-
match self.0 {}
199+
Err(io::Error::new(ErrorKind::Other, "not supported"))
129200
}
130201

131202
pub fn ttl(&self) -> io::Result<u32> {
132-
match self.0 {}
203+
Err(io::Error::new(ErrorKind::Other, "not supported"))
133204
}
134205

135206
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
136-
match self.0 {}
207+
Err(io::Error::new(ErrorKind::Other, "not supported"))
137208
}
138209

139210
pub fn only_v6(&self) -> io::Result<bool> {
140-
match self.0 {}
211+
Err(io::Error::new(ErrorKind::Other, "not supported"))
141212
}
142213

143214
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
144-
match self.0 {}
215+
Err(io::Error::new(ErrorKind::Other, "not supported"))
145216
}
146217

147218
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
148-
match self.0 {}
219+
Err(io::Error::new(ErrorKind::Other, "not supported"))
149220
}
150221
}
151222

152223
impl fmt::Debug for TcpListener {
153224
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
154-
match self.0 {}
225+
Ok(())
155226
}
156227
}
157228

158-
pub struct UdpSocket(Void);
229+
pub struct UdpSocket(abi::Handle);
159230

160231
impl UdpSocket {
161232
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
162-
unsupported()
233+
Err(io::Error::new(ErrorKind::Other, "not supported"))
163234
}
164235

165236
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
166-
match self.0 {}
237+
Err(io::Error::new(ErrorKind::Other, "not supported"))
167238
}
168239

169240
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
170-
match self.0 {}
241+
Err(io::Error::new(ErrorKind::Other, "not supported"))
171242
}
172243

173244
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
174-
match self.0 {}
245+
Err(io::Error::new(ErrorKind::Other, "not supported"))
175246
}
176247

177248
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
178-
match self.0 {}
249+
Err(io::Error::new(ErrorKind::Other, "not supported"))
179250
}
180251

181252
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
182-
match self.0 {}
253+
Err(io::Error::new(ErrorKind::Other, "not supported"))
183254
}
184255

185256
pub fn duplicate(&self) -> io::Result<UdpSocket> {
186-
match self.0 {}
257+
Err(io::Error::new(ErrorKind::Other, "not supported"))
187258
}
188259

189260
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
190-
match self.0 {}
261+
Err(io::Error::new(ErrorKind::Other, "not supported"))
191262
}
192263

193264
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
194-
match self.0 {}
265+
Err(io::Error::new(ErrorKind::Other, "not supported"))
195266
}
196267

197268
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
198-
match self.0 {}
269+
Err(io::Error::new(ErrorKind::Other, "not supported"))
199270
}
200271

201272
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
202-
match self.0 {}
273+
Err(io::Error::new(ErrorKind::Other, "not supported"))
203274
}
204275

205276
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
206-
match self.0 {}
277+
Err(io::Error::new(ErrorKind::Other, "not supported"))
207278
}
208279

209280
pub fn broadcast(&self) -> io::Result<bool> {
210-
match self.0 {}
281+
Err(io::Error::new(ErrorKind::Other, "not supported"))
211282
}
212283

213284
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
214-
match self.0 {}
285+
Err(io::Error::new(ErrorKind::Other, "not supported"))
215286
}
216287

217288
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
218-
match self.0 {}
289+
Err(io::Error::new(ErrorKind::Other, "not supported"))
219290
}
220291

221292
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
222-
match self.0 {}
293+
Err(io::Error::new(ErrorKind::Other, "not supported"))
223294
}
224295

225296
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
226-
match self.0 {}
297+
Err(io::Error::new(ErrorKind::Other, "not supported"))
227298
}
228299

229300
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
230-
match self.0 {}
301+
Err(io::Error::new(ErrorKind::Other, "not supported"))
231302
}
232303

233304
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
234-
match self.0 {}
305+
Err(io::Error::new(ErrorKind::Other, "not supported"))
235306
}
236307

237308
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
238-
match self.0 {}
309+
Err(io::Error::new(ErrorKind::Other, "not supported"))
239310
}
240311

241312
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
242-
match self.0 {}
313+
Err(io::Error::new(ErrorKind::Other, "not supported"))
243314
}
244315

245316
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
246-
match self.0 {}
317+
Err(io::Error::new(ErrorKind::Other, "not supported"))
247318
}
248319

249320
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
250-
match self.0 {}
321+
Err(io::Error::new(ErrorKind::Other, "not supported"))
251322
}
252323

253324
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
254-
match self.0 {}
325+
Err(io::Error::new(ErrorKind::Other, "not supported"))
255326
}
256327

257328
pub fn ttl(&self) -> io::Result<u32> {
258-
match self.0 {}
329+
Err(io::Error::new(ErrorKind::Other, "not supported"))
259330
}
260331

261332
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
262-
match self.0 {}
333+
Err(io::Error::new(ErrorKind::Other, "not supported"))
263334
}
264335

265336
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
266-
match self.0 {}
337+
Err(io::Error::new(ErrorKind::Other, "not supported"))
267338
}
268339

269340
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
270-
match self.0 {}
341+
Err(io::Error::new(ErrorKind::Other, "not supported"))
271342
}
272343

273344
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
274-
match self.0 {}
345+
Err(io::Error::new(ErrorKind::Other, "not supported"))
275346
}
276347

277348
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
278-
match self.0 {}
349+
Err(io::Error::new(ErrorKind::Other, "not supported"))
279350
}
280351

281352
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
282-
match self.0 {}
353+
Err(io::Error::new(ErrorKind::Other, "not supported"))
283354
}
284355
}
285356

286357
impl fmt::Debug for UdpSocket {
287358
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
288-
match self.0 {}
359+
Ok(())
289360
}
290361
}
291362

0 commit comments

Comments
 (0)
Please sign in to comment.