]>
Commit | Line | Data |
---|---|---|
1b1a35ee XL |
1 | #![deny(unsafe_op_in_unsafe_fn)] |
2 | ||
5099ac24 | 3 | use super::err2io; |
6a06907d | 4 | use super::fd::WasiFd; |
532ac7d7 | 5 | use crate::fmt; |
48663c56 | 6 | use crate::io::{self, IoSlice, IoSliceMut}; |
60c5eb7d | 7 | use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; |
94222f64 | 8 | use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; |
cdc7bbd5 | 9 | use crate::sys::unsupported; |
94222f64 | 10 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
60c5eb7d | 11 | use crate::time::Duration; |
532ac7d7 | 12 | |
94222f64 XL |
13 | pub struct Socket(WasiFd); |
14 | ||
48663c56 | 15 | pub struct TcpStream { |
94222f64 XL |
16 | inner: Socket, |
17 | } | |
18 | ||
19 | impl AsInner<WasiFd> for Socket { | |
20 | fn as_inner(&self) -> &WasiFd { | |
21 | &self.0 | |
22 | } | |
23 | } | |
24 | ||
25 | impl IntoInner<WasiFd> for Socket { | |
26 | fn into_inner(self) -> WasiFd { | |
27 | self.0 | |
28 | } | |
29 | } | |
30 | ||
31 | impl FromInner<WasiFd> for Socket { | |
32 | fn from_inner(inner: WasiFd) -> Socket { | |
33 | Socket(inner) | |
34 | } | |
35 | } | |
36 | ||
37 | impl AsFd for Socket { | |
38 | fn as_fd(&self) -> BorrowedFd<'_> { | |
39 | self.0.as_fd() | |
40 | } | |
41 | } | |
42 | ||
43 | impl AsRawFd for Socket { | |
44 | fn as_raw_fd(&self) -> RawFd { | |
45 | self.0.as_raw_fd() | |
46 | } | |
47 | } | |
48 | ||
49 | impl IntoRawFd for Socket { | |
50 | fn into_raw_fd(self) -> RawFd { | |
51 | self.0.into_raw_fd() | |
52 | } | |
53 | } | |
54 | ||
55 | impl FromRawFd for Socket { | |
56 | unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | |
57 | unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } | |
58 | } | |
48663c56 | 59 | } |
532ac7d7 XL |
60 | |
61 | impl TcpStream { | |
62 | pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { | |
63 | unsupported() | |
64 | } | |
65 | ||
66 | pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { | |
67 | unsupported() | |
68 | } | |
69 | ||
70 | pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { | |
48663c56 | 71 | unsupported() |
532ac7d7 XL |
72 | } |
73 | ||
74 | pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { | |
48663c56 | 75 | unsupported() |
532ac7d7 XL |
76 | } |
77 | ||
78 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> { | |
48663c56 | 79 | unsupported() |
532ac7d7 XL |
80 | } |
81 | ||
82 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> { | |
48663c56 | 83 | unsupported() |
532ac7d7 XL |
84 | } |
85 | ||
86 | pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { | |
48663c56 | 87 | unsupported() |
532ac7d7 XL |
88 | } |
89 | ||
5099ac24 FG |
90 | pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { |
91 | self.read_vectored(&mut [IoSliceMut::new(buf)]) | |
532ac7d7 XL |
92 | } |
93 | ||
5099ac24 FG |
94 | pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
95 | self.socket().as_inner().read(bufs) | |
532ac7d7 XL |
96 | } |
97 | ||
f9f354fc XL |
98 | pub fn is_read_vectored(&self) -> bool { |
99 | true | |
100 | } | |
101 | ||
5099ac24 FG |
102 | pub fn write(&self, buf: &[u8]) -> io::Result<usize> { |
103 | self.write_vectored(&[IoSlice::new(buf)]) | |
532ac7d7 XL |
104 | } |
105 | ||
5099ac24 FG |
106 | pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
107 | self.socket().as_inner().write(bufs) | |
532ac7d7 XL |
108 | } |
109 | ||
f9f354fc XL |
110 | pub fn is_write_vectored(&self) -> bool { |
111 | true | |
112 | } | |
113 | ||
532ac7d7 | 114 | pub fn peer_addr(&self) -> io::Result<SocketAddr> { |
48663c56 | 115 | unsupported() |
532ac7d7 XL |
116 | } |
117 | ||
118 | pub fn socket_addr(&self) -> io::Result<SocketAddr> { | |
48663c56 | 119 | unsupported() |
532ac7d7 XL |
120 | } |
121 | ||
122 | pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { | |
48663c56 | 123 | unsupported() |
532ac7d7 XL |
124 | } |
125 | ||
126 | pub fn duplicate(&self) -> io::Result<TcpStream> { | |
48663c56 | 127 | unsupported() |
532ac7d7 XL |
128 | } |
129 | ||
94222f64 XL |
130 | pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { |
131 | unsupported() | |
132 | } | |
133 | ||
134 | pub fn linger(&self) -> io::Result<Option<Duration>> { | |
135 | unsupported() | |
136 | } | |
137 | ||
532ac7d7 | 138 | pub fn set_nodelay(&self, _: bool) -> io::Result<()> { |
48663c56 | 139 | unsupported() |
532ac7d7 XL |
140 | } |
141 | ||
142 | pub fn nodelay(&self) -> io::Result<bool> { | |
48663c56 | 143 | unsupported() |
532ac7d7 XL |
144 | } |
145 | ||
146 | pub fn set_ttl(&self, _: u32) -> io::Result<()> { | |
48663c56 | 147 | unsupported() |
532ac7d7 XL |
148 | } |
149 | ||
150 | pub fn ttl(&self) -> io::Result<u32> { | |
48663c56 | 151 | unsupported() |
532ac7d7 XL |
152 | } |
153 | ||
154 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { | |
48663c56 | 155 | unsupported() |
532ac7d7 XL |
156 | } |
157 | ||
5099ac24 FG |
158 | pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { |
159 | let fdstat = unsafe { | |
160 | wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)? | |
161 | }; | |
162 | ||
163 | let mut flags = fdstat.fs_flags; | |
164 | ||
165 | if state { | |
166 | flags |= wasi::FDFLAGS_NONBLOCK; | |
167 | } else { | |
168 | flags &= !wasi::FDFLAGS_NONBLOCK; | |
169 | } | |
170 | ||
171 | unsafe { | |
172 | wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags) | |
173 | .map_err(err2io) | |
174 | } | |
48663c56 XL |
175 | } |
176 | ||
94222f64 XL |
177 | pub fn socket(&self) -> &Socket { |
178 | &self.inner | |
48663c56 XL |
179 | } |
180 | ||
94222f64 XL |
181 | pub fn into_socket(self) -> Socket { |
182 | self.inner | |
48663c56 XL |
183 | } |
184 | } | |
185 | ||
94222f64 XL |
186 | impl FromInner<Socket> for TcpStream { |
187 | fn from_inner(socket: Socket) -> TcpStream { | |
188 | TcpStream { inner: socket } | |
532ac7d7 XL |
189 | } |
190 | } | |
191 | ||
192 | impl fmt::Debug for TcpStream { | |
48663c56 | 193 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94222f64 | 194 | f.debug_struct("TcpStream").field("fd", &self.inner.as_raw_fd()).finish() |
532ac7d7 XL |
195 | } |
196 | } | |
197 | ||
48663c56 | 198 | pub struct TcpListener { |
94222f64 | 199 | inner: Socket, |
48663c56 | 200 | } |
532ac7d7 XL |
201 | |
202 | impl TcpListener { | |
203 | pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { | |
204 | unsupported() | |
205 | } | |
206 | ||
207 | pub fn socket_addr(&self) -> io::Result<SocketAddr> { | |
48663c56 | 208 | unsupported() |
532ac7d7 XL |
209 | } |
210 | ||
211 | pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { | |
5099ac24 FG |
212 | let fd = unsafe { |
213 | wasi::sock_accept(self.as_inner().as_inner().as_raw_fd() as _, 0).map_err(err2io)? | |
214 | }; | |
215 | ||
216 | Ok(( | |
217 | TcpStream::from_inner(unsafe { Socket::from_raw_fd(fd as _) }), | |
218 | // WASI has no concept of SocketAddr yet | |
219 | // return an unspecified IPv4Addr | |
220 | SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0), | |
221 | )) | |
532ac7d7 XL |
222 | } |
223 | ||
224 | pub fn duplicate(&self) -> io::Result<TcpListener> { | |
48663c56 | 225 | unsupported() |
532ac7d7 XL |
226 | } |
227 | ||
228 | pub fn set_ttl(&self, _: u32) -> io::Result<()> { | |
48663c56 | 229 | unsupported() |
532ac7d7 XL |
230 | } |
231 | ||
232 | pub fn ttl(&self) -> io::Result<u32> { | |
48663c56 | 233 | unsupported() |
532ac7d7 XL |
234 | } |
235 | ||
236 | pub fn set_only_v6(&self, _: bool) -> io::Result<()> { | |
48663c56 | 237 | unsupported() |
532ac7d7 XL |
238 | } |
239 | ||
240 | pub fn only_v6(&self) -> io::Result<bool> { | |
48663c56 | 241 | unsupported() |
532ac7d7 XL |
242 | } |
243 | ||
244 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { | |
48663c56 | 245 | unsupported() |
532ac7d7 XL |
246 | } |
247 | ||
5099ac24 FG |
248 | pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { |
249 | let fdstat = unsafe { | |
250 | wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)? | |
251 | }; | |
252 | ||
253 | let mut flags = fdstat.fs_flags; | |
254 | ||
255 | if state { | |
256 | flags |= wasi::FDFLAGS_NONBLOCK; | |
257 | } else { | |
258 | flags &= !wasi::FDFLAGS_NONBLOCK; | |
259 | } | |
260 | ||
261 | unsafe { | |
262 | wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags) | |
263 | .map_err(err2io) | |
264 | } | |
48663c56 XL |
265 | } |
266 | ||
94222f64 XL |
267 | pub fn socket(&self) -> &Socket { |
268 | &self.inner | |
269 | } | |
270 | ||
271 | pub fn into_socket(self) -> Socket { | |
272 | self.inner | |
48663c56 | 273 | } |
94222f64 | 274 | } |
48663c56 | 275 | |
94222f64 XL |
276 | impl AsInner<Socket> for TcpListener { |
277 | fn as_inner(&self) -> &Socket { | |
278 | &self.inner | |
48663c56 XL |
279 | } |
280 | } | |
281 | ||
94222f64 XL |
282 | impl IntoInner<Socket> for TcpListener { |
283 | fn into_inner(self) -> Socket { | |
284 | self.inner | |
285 | } | |
286 | } | |
287 | ||
288 | impl FromInner<Socket> for TcpListener { | |
289 | fn from_inner(inner: Socket) -> TcpListener { | |
290 | TcpListener { inner } | |
532ac7d7 XL |
291 | } |
292 | } | |
293 | ||
294 | impl fmt::Debug for TcpListener { | |
48663c56 | 295 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94222f64 | 296 | f.debug_struct("TcpListener").field("fd", &self.inner.as_raw_fd()).finish() |
532ac7d7 XL |
297 | } |
298 | } | |
299 | ||
48663c56 | 300 | pub struct UdpSocket { |
94222f64 | 301 | inner: Socket, |
48663c56 | 302 | } |
532ac7d7 XL |
303 | |
304 | impl UdpSocket { | |
305 | pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { | |
306 | unsupported() | |
307 | } | |
308 | ||
309 | pub fn peer_addr(&self) -> io::Result<SocketAddr> { | |
48663c56 | 310 | unsupported() |
532ac7d7 XL |
311 | } |
312 | ||
313 | pub fn socket_addr(&self) -> io::Result<SocketAddr> { | |
48663c56 | 314 | unsupported() |
532ac7d7 XL |
315 | } |
316 | ||
317 | pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { | |
48663c56 | 318 | unsupported() |
532ac7d7 XL |
319 | } |
320 | ||
321 | pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { | |
48663c56 | 322 | unsupported() |
532ac7d7 XL |
323 | } |
324 | ||
325 | pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { | |
48663c56 | 326 | unsupported() |
532ac7d7 XL |
327 | } |
328 | ||
329 | pub fn duplicate(&self) -> io::Result<UdpSocket> { | |
48663c56 | 330 | unsupported() |
532ac7d7 XL |
331 | } |
332 | ||
333 | pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { | |
48663c56 | 334 | unsupported() |
532ac7d7 XL |
335 | } |
336 | ||
337 | pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { | |
48663c56 | 338 | unsupported() |
532ac7d7 XL |
339 | } |
340 | ||
341 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> { | |
48663c56 | 342 | unsupported() |
532ac7d7 XL |
343 | } |
344 | ||
345 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> { | |
48663c56 | 346 | unsupported() |
532ac7d7 XL |
347 | } |
348 | ||
349 | pub fn set_broadcast(&self, _: bool) -> io::Result<()> { | |
48663c56 | 350 | unsupported() |
532ac7d7 XL |
351 | } |
352 | ||
353 | pub fn broadcast(&self) -> io::Result<bool> { | |
48663c56 | 354 | unsupported() |
532ac7d7 XL |
355 | } |
356 | ||
357 | pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { | |
48663c56 | 358 | unsupported() |
532ac7d7 XL |
359 | } |
360 | ||
361 | pub fn multicast_loop_v4(&self) -> io::Result<bool> { | |
48663c56 | 362 | unsupported() |
532ac7d7 XL |
363 | } |
364 | ||
365 | pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { | |
48663c56 | 366 | unsupported() |
532ac7d7 XL |
367 | } |
368 | ||
369 | pub fn multicast_ttl_v4(&self) -> io::Result<u32> { | |
48663c56 | 370 | unsupported() |
532ac7d7 XL |
371 | } |
372 | ||
373 | pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { | |
48663c56 | 374 | unsupported() |
532ac7d7 XL |
375 | } |
376 | ||
377 | pub fn multicast_loop_v6(&self) -> io::Result<bool> { | |
48663c56 | 378 | unsupported() |
532ac7d7 XL |
379 | } |
380 | ||
60c5eb7d | 381 | pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { |
48663c56 | 382 | unsupported() |
532ac7d7 XL |
383 | } |
384 | ||
60c5eb7d | 385 | pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { |
48663c56 | 386 | unsupported() |
532ac7d7 XL |
387 | } |
388 | ||
60c5eb7d | 389 | pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { |
48663c56 | 390 | unsupported() |
532ac7d7 XL |
391 | } |
392 | ||
60c5eb7d | 393 | pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { |
48663c56 | 394 | unsupported() |
532ac7d7 XL |
395 | } |
396 | ||
397 | pub fn set_ttl(&self, _: u32) -> io::Result<()> { | |
48663c56 | 398 | unsupported() |
532ac7d7 XL |
399 | } |
400 | ||
401 | pub fn ttl(&self) -> io::Result<u32> { | |
48663c56 | 402 | unsupported() |
532ac7d7 XL |
403 | } |
404 | ||
405 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { | |
48663c56 | 406 | unsupported() |
532ac7d7 XL |
407 | } |
408 | ||
409 | pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { | |
48663c56 | 410 | unsupported() |
532ac7d7 XL |
411 | } |
412 | ||
413 | pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { | |
48663c56 | 414 | unsupported() |
532ac7d7 XL |
415 | } |
416 | ||
417 | pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { | |
48663c56 | 418 | unsupported() |
532ac7d7 XL |
419 | } |
420 | ||
421 | pub fn send(&self, _: &[u8]) -> io::Result<usize> { | |
48663c56 | 422 | unsupported() |
532ac7d7 XL |
423 | } |
424 | ||
425 | pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { | |
48663c56 XL |
426 | unsupported() |
427 | } | |
428 | ||
94222f64 XL |
429 | pub fn socket(&self) -> &Socket { |
430 | &self.inner | |
431 | } | |
432 | ||
433 | pub fn into_socket(self) -> Socket { | |
434 | self.inner | |
48663c56 | 435 | } |
94222f64 XL |
436 | } |
437 | ||
438 | impl AsInner<Socket> for UdpSocket { | |
439 | fn as_inner(&self) -> &Socket { | |
440 | &self.inner | |
441 | } | |
442 | } | |
48663c56 | 443 | |
94222f64 XL |
444 | impl IntoInner<Socket> for UdpSocket { |
445 | fn into_inner(self) -> Socket { | |
446 | self.inner | |
48663c56 XL |
447 | } |
448 | } | |
449 | ||
94222f64 XL |
450 | impl FromInner<Socket> for UdpSocket { |
451 | fn from_inner(inner: Socket) -> UdpSocket { | |
452 | UdpSocket { inner } | |
532ac7d7 XL |
453 | } |
454 | } | |
455 | ||
456 | impl fmt::Debug for UdpSocket { | |
48663c56 | 457 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94222f64 | 458 | f.debug_struct("UdpSocket").field("fd", &self.inner.as_raw_fd()).finish() |
532ac7d7 XL |
459 | } |
460 | } | |
461 | ||
cdc7bbd5 | 462 | pub struct LookupHost(!); |
532ac7d7 XL |
463 | |
464 | impl LookupHost { | |
465 | pub fn port(&self) -> u16 { | |
cdc7bbd5 | 466 | self.0 |
532ac7d7 XL |
467 | } |
468 | } | |
469 | ||
470 | impl Iterator for LookupHost { | |
471 | type Item = SocketAddr; | |
472 | fn next(&mut self) -> Option<SocketAddr> { | |
cdc7bbd5 | 473 | self.0 |
532ac7d7 XL |
474 | } |
475 | } | |
476 | ||
477 | impl<'a> TryFrom<&'a str> for LookupHost { | |
478 | type Error = io::Error; | |
479 | ||
480 | fn try_from(_v: &'a str) -> io::Result<LookupHost> { | |
481 | unsupported() | |
482 | } | |
483 | } | |
484 | ||
485 | impl<'a> TryFrom<(&'a str, u16)> for LookupHost { | |
486 | type Error = io::Error; | |
487 | ||
488 | fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { | |
489 | unsupported() | |
490 | } | |
491 | } | |
492 | ||
493 | #[allow(nonstandard_style)] | |
494 | pub mod netc { | |
495 | pub const AF_INET: u8 = 0; | |
496 | pub const AF_INET6: u8 = 1; | |
497 | pub type sa_family_t = u8; | |
498 | ||
499 | #[derive(Copy, Clone)] | |
500 | pub struct in_addr { | |
501 | pub s_addr: u32, | |
502 | } | |
503 | ||
504 | #[derive(Copy, Clone)] | |
505 | pub struct sockaddr_in { | |
506 | pub sin_family: sa_family_t, | |
507 | pub sin_port: u16, | |
508 | pub sin_addr: in_addr, | |
509 | } | |
510 | ||
511 | #[derive(Copy, Clone)] | |
512 | pub struct in6_addr { | |
513 | pub s6_addr: [u8; 16], | |
514 | } | |
515 | ||
516 | #[derive(Copy, Clone)] | |
517 | pub struct sockaddr_in6 { | |
518 | pub sin6_family: sa_family_t, | |
519 | pub sin6_port: u16, | |
520 | pub sin6_addr: in6_addr, | |
521 | pub sin6_flowinfo: u32, | |
522 | pub sin6_scope_id: u32, | |
523 | } | |
524 | ||
525 | #[derive(Copy, Clone)] | |
60c5eb7d | 526 | pub struct sockaddr {} |
532ac7d7 XL |
527 | |
528 | pub type socklen_t = usize; | |
529 | } |