1
1
#![ deny( unsafe_op_in_unsafe_fn) ]
2
2
3
+ use super :: err2io;
3
4
use super :: fd:: WasiFd ;
4
5
use crate :: convert:: TryFrom ;
5
6
use crate :: fmt;
@@ -87,24 +88,24 @@ impl TcpStream {
87
88
unsupported ( )
88
89
}
89
90
90
- pub fn read ( & self , _ : & mut [ u8 ] ) -> io:: Result < usize > {
91
- unsupported ( )
91
+ pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
92
+ self . read_vectored ( & mut [ IoSliceMut :: new ( buf ) ] )
92
93
}
93
94
94
- pub fn read_vectored ( & self , _ : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
95
- unsupported ( )
95
+ pub fn read_vectored ( & self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
96
+ self . socket ( ) . as_inner ( ) . read ( bufs )
96
97
}
97
98
98
99
pub fn is_read_vectored ( & self ) -> bool {
99
100
true
100
101
}
101
102
102
- pub fn write ( & self , _ : & [ u8 ] ) -> io:: Result < usize > {
103
- unsupported ( )
103
+ pub fn write ( & self , buf : & [ u8 ] ) -> io:: Result < usize > {
104
+ self . write_vectored ( & [ IoSlice :: new ( buf ) ] )
104
105
}
105
106
106
- pub fn write_vectored ( & self , _ : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
107
- unsupported ( )
107
+ pub fn write_vectored ( & self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
108
+ self . socket ( ) . as_inner ( ) . write ( bufs )
108
109
}
109
110
110
111
pub fn is_write_vectored ( & self ) -> bool {
@@ -155,8 +156,23 @@ impl TcpStream {
155
156
unsupported ( )
156
157
}
157
158
158
- pub fn set_nonblocking ( & self , _: bool ) -> io:: Result < ( ) > {
159
- unsupported ( )
159
+ pub fn set_nonblocking ( & self , state : bool ) -> io:: Result < ( ) > {
160
+ let fdstat = unsafe {
161
+ wasi:: fd_fdstat_get ( self . socket ( ) . as_inner ( ) . as_raw_fd ( ) as wasi:: Fd ) . map_err ( err2io) ?
162
+ } ;
163
+
164
+ let mut flags = fdstat. fs_flags ;
165
+
166
+ if state {
167
+ flags |= wasi:: FDFLAGS_NONBLOCK ;
168
+ } else {
169
+ flags &= !wasi:: FDFLAGS_NONBLOCK ;
170
+ }
171
+
172
+ unsafe {
173
+ wasi:: fd_fdstat_set_flags ( self . socket ( ) . as_inner ( ) . as_raw_fd ( ) as wasi:: Fd , flags)
174
+ . map_err ( err2io)
175
+ }
160
176
}
161
177
162
178
pub fn socket ( & self ) -> & Socket {
@@ -194,7 +210,16 @@ impl TcpListener {
194
210
}
195
211
196
212
pub fn accept ( & self ) -> io:: Result < ( TcpStream , SocketAddr ) > {
197
- unsupported ( )
213
+ let fd = unsafe {
214
+ wasi:: sock_accept ( self . as_inner ( ) . as_inner ( ) . as_raw_fd ( ) as _ , 0 ) . map_err ( err2io) ?
215
+ } ;
216
+
217
+ Ok ( (
218
+ TcpStream :: from_inner ( unsafe { Socket :: from_raw_fd ( fd as _ ) } ) ,
219
+ // WASI has no concept of SocketAddr yet
220
+ // return an unspecified IPv4Addr
221
+ SocketAddr :: new ( Ipv4Addr :: UNSPECIFIED . into ( ) , 0 ) ,
222
+ ) )
198
223
}
199
224
200
225
pub fn duplicate ( & self ) -> io:: Result < TcpListener > {
@@ -221,8 +246,23 @@ impl TcpListener {
221
246
unsupported ( )
222
247
}
223
248
224
- pub fn set_nonblocking ( & self , _: bool ) -> io:: Result < ( ) > {
225
- unsupported ( )
249
+ pub fn set_nonblocking ( & self , state : bool ) -> io:: Result < ( ) > {
250
+ let fdstat = unsafe {
251
+ wasi:: fd_fdstat_get ( self . socket ( ) . as_inner ( ) . as_raw_fd ( ) as wasi:: Fd ) . map_err ( err2io) ?
252
+ } ;
253
+
254
+ let mut flags = fdstat. fs_flags ;
255
+
256
+ if state {
257
+ flags |= wasi:: FDFLAGS_NONBLOCK ;
258
+ } else {
259
+ flags &= !wasi:: FDFLAGS_NONBLOCK ;
260
+ }
261
+
262
+ unsafe {
263
+ wasi:: fd_fdstat_set_flags ( self . socket ( ) . as_inner ( ) . as_raw_fd ( ) as wasi:: Fd , flags)
264
+ . map_err ( err2io)
265
+ }
226
266
}
227
267
228
268
pub fn socket ( & self ) -> & Socket {
0 commit comments