11use crate :: convert:: TryFrom ;
22use crate :: fmt;
33use crate :: io:: { self , ErrorKind , IoSlice , IoSliceMut } ;
4- use crate :: net:: { Ipv4Addr , Ipv6Addr , Shutdown , SocketAddr } ;
4+ use crate :: net:: { IpAddr , Ipv4Addr , Ipv6Addr , Shutdown , SocketAddr } ;
55use crate :: str;
6+ use crate :: sync:: Arc ;
67use crate :: sys:: hermit:: abi;
8+ use crate :: sys:: hermit:: abi:: IpAddress :: { Ipv4 , Ipv6 } ;
79use crate :: sys:: { unsupported, Void } ;
10+ use crate :: sys_common:: AsInner ;
811use crate :: time:: Duration ;
912
1013/// Checks whether the HermitCore's socket interface has been started already, and
@@ -17,14 +20,33 @@ pub fn init() -> io::Result<()> {
1720 Ok ( ( ) )
1821}
1922
20- pub struct TcpStream ( abi:: Handle ) ;
23+ #[ derive( Debug , Clone ) ]
24+ pub struct Socket ( abi:: Handle ) ;
25+
26+ impl AsInner < abi:: Handle > for Socket {
27+ fn as_inner ( & self ) -> & abi:: Handle {
28+ & self . 0
29+ }
30+ }
31+
32+ impl Drop for Socket {
33+ fn drop ( & mut self ) {
34+ let _ = abi:: tcpstream:: close ( self . 0 ) ;
35+ }
36+ }
37+
38+ // Arc is used to count the number of used sockets.
39+ // Only if all sockets are released, the drop
40+ // method will close the socket.
41+ #[ derive( Clone ) ]
42+ pub struct TcpStream ( Arc < Socket > ) ;
2143
2244impl TcpStream {
2345 pub fn connect ( addr : io:: Result < & SocketAddr > ) -> io:: Result < TcpStream > {
2446 let addr = addr?;
2547
2648 match abi:: tcpstream:: connect ( addr. ip ( ) . to_string ( ) . as_bytes ( ) , addr. port ( ) , None ) {
27- Ok ( handle) => Ok ( TcpStream ( handle) ) ,
49+ Ok ( handle) => Ok ( TcpStream ( Arc :: new ( Socket ( handle) ) ) ) ,
2850 _ => {
2951 Err ( io:: Error :: new ( ErrorKind :: Other , "Unable to initiate a connection on a socket" ) )
3052 }
@@ -37,39 +59,42 @@ impl TcpStream {
3759 saddr. port ( ) ,
3860 Some ( duration. as_millis ( ) as u64 ) ,
3961 ) {
40- Ok ( handle) => Ok ( TcpStream ( handle) ) ,
62+ Ok ( handle) => Ok ( TcpStream ( Arc :: new ( Socket ( handle) ) ) ) ,
4163 _ => {
4264 Err ( io:: Error :: new ( ErrorKind :: Other , "Unable to initiate a connection on a socket" ) )
4365 }
4466 }
4567 }
4668
4769 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 ) )
70+ abi:: tcpstream:: set_read_timeout ( * self . 0 . as_inner ( ) , duration. map ( |d| d. as_millis ( ) as u64 ) )
4971 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to set timeout value" ) )
5072 }
5173
5274 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" ) )
75+ abi:: tcpstream:: set_write_timeout (
76+ * self . 0 . as_inner ( ) ,
77+ duration. map ( |d| d. as_millis ( ) as u64 ) ,
78+ )
79+ . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to set timeout value" ) )
5580 }
5681
5782 pub fn read_timeout ( & self ) -> io:: Result < Option < Duration > > {
58- let duration = abi:: tcpstream:: get_read_timeout ( self . 0 )
83+ let duration = abi:: tcpstream:: get_read_timeout ( * self . 0 . as_inner ( ) )
5984 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to determine timeout value" ) ) ?;
6085
6186 Ok ( duration. map ( |d| Duration :: from_millis ( d) ) )
6287 }
6388
6489 pub fn write_timeout ( & self ) -> io:: Result < Option < Duration > > {
65- let duration = abi:: tcpstream:: get_write_timeout ( self . 0 )
90+ let duration = abi:: tcpstream:: get_write_timeout ( * self . 0 . as_inner ( ) )
6691 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to determine timeout value" ) ) ?;
6792
6893 Ok ( duration. map ( |d| Duration :: from_millis ( d) ) )
6994 }
7095
7196 pub fn peek ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
72- abi:: tcpstream:: peek ( self . 0 , buf)
97+ abi:: tcpstream:: peek ( * self . 0 . as_inner ( ) , buf)
7398 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "set_nodelay failed" ) )
7499 }
75100
@@ -81,18 +106,11 @@ impl TcpStream {
81106 let mut size: usize = 0 ;
82107
83108 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- }
109+ let ret = abi:: tcpstream:: read ( * self . 0 . as_inner ( ) , & mut i[ 0 ..] )
110+ . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to read on socket" ) ) ?;
111+
112+ if ret != 0 {
113+ size += ret;
96114 }
97115 }
98116
@@ -112,7 +130,7 @@ impl TcpStream {
112130 let mut size: usize = 0 ;
113131
114132 for i in ioslice. iter ( ) {
115- size += abi:: tcpstream:: write ( self . 0 , i)
133+ size += abi:: tcpstream:: write ( * self . 0 . as_inner ( ) , i)
116134 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "Unable to write on socket" ) ) ?;
117135 }
118136
@@ -125,42 +143,53 @@ impl TcpStream {
125143 }
126144
127145 pub fn peer_addr ( & self ) -> io:: Result < SocketAddr > {
128- Err ( io:: Error :: new ( ErrorKind :: Other , "peer_addr isn't supported" ) )
146+ let ( ipaddr, port) = abi:: tcpstream:: peer_addr ( * self . 0 . as_inner ( ) )
147+ . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "peer_addr failed" ) ) ?;
148+
149+ let saddr = match ipaddr {
150+ Ipv4 ( ref addr) => SocketAddr :: new (
151+ IpAddr :: V4 ( Ipv4Addr :: new ( addr. 0 [ 0 ] , addr. 0 [ 1 ] , addr. 0 [ 2 ] , addr. 0 [ 3 ] ) ) ,
152+ port,
153+ ) ,
154+ Ipv6 ( ref addr) => SocketAddr :: new ( IpAddr :: V6 ( Ipv6Addr :: from ( addr. 0 ) ) , port) ,
155+ _ => {
156+ return Err ( io:: Error :: new ( ErrorKind :: Other , "peer_addr failed" ) ) ;
157+ }
158+ } ;
159+
160+ Ok ( saddr)
129161 }
130162
131163 pub fn socket_addr ( & self ) -> io:: Result < SocketAddr > {
132164 Err ( io:: Error :: new ( ErrorKind :: Other , "socket_addr isn't supported" ) )
133165 }
134166
135167 pub fn shutdown ( & self , how : Shutdown ) -> io:: Result < ( ) > {
136- abi:: tcpstream:: shutdown ( self . 0 , how as i32 )
168+ abi:: tcpstream:: shutdown ( * self . 0 . as_inner ( ) , how as i32 )
137169 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "unable to shutdown socket" ) )
138170 }
139171
140172 pub fn duplicate ( & self ) -> io:: Result < TcpStream > {
141- let handle = abi:: tcpstream:: duplicate ( self . 0 )
142- . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "unable to duplicate stream" ) ) ?;
143-
144- Ok ( TcpStream ( handle) )
173+ Ok ( self . clone ( ) )
145174 }
146175
147176 pub fn set_nodelay ( & self , mode : bool ) -> io:: Result < ( ) > {
148- abi:: tcpstream:: set_nodelay ( self . 0 , mode)
177+ abi:: tcpstream:: set_nodelay ( * self . 0 . as_inner ( ) , mode)
149178 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "set_nodelay failed" ) )
150179 }
151180
152181 pub fn nodelay ( & self ) -> io:: Result < bool > {
153- abi:: tcpstream:: nodelay ( self . 0 )
182+ abi:: tcpstream:: nodelay ( * self . 0 . as_inner ( ) )
154183 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "nodelay failed" ) )
155184 }
156185
157186 pub fn set_ttl ( & self , tll : u32 ) -> io:: Result < ( ) > {
158- abi:: tcpstream:: set_tll ( self . 0 , tll)
187+ abi:: tcpstream:: set_tll ( * self . 0 . as_inner ( ) , tll)
159188 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "unable to set TTL" ) )
160189 }
161190
162191 pub fn ttl ( & self ) -> io:: Result < u32 > {
163- abi:: tcpstream:: get_tll ( self . 0 )
192+ abi:: tcpstream:: get_tll ( * self . 0 . as_inner ( ) )
164193 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "unable to get TTL" ) )
165194 }
166195
@@ -169,40 +198,50 @@ impl TcpStream {
169198 }
170199
171200 pub fn set_nonblocking ( & self , mode : bool ) -> io:: Result < ( ) > {
172- abi:: tcpstream:: set_nonblocking ( self . 0 , mode)
201+ abi:: tcpstream:: set_nonblocking ( * self . 0 . as_inner ( ) , mode)
173202 . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "unable to set blocking mode" ) )
174203 }
175204}
176205
177- impl Drop for TcpStream {
178- fn drop ( & mut self ) {
179- let _ = abi:: tcpstream:: close ( self . 0 ) ;
180- }
181- }
182-
183206impl fmt:: Debug for TcpStream {
184207 fn fmt ( & self , _f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
185208 Ok ( ( ) )
186209 }
187210}
188211
189- pub struct TcpListener ( abi:: Handle ) ;
212+ #[ derive( Clone ) ]
213+ pub struct TcpListener ( SocketAddr ) ;
190214
191215impl TcpListener {
192- pub fn bind ( _: io:: Result < & SocketAddr > ) -> io:: Result < TcpListener > {
193- Err ( io:: Error :: new ( ErrorKind :: Other , "not supported" ) )
216+ pub fn bind ( addr : io:: Result < & SocketAddr > ) -> io:: Result < TcpListener > {
217+ let addr = addr?;
218+
219+ Ok ( TcpListener ( * addr) )
194220 }
195221
196222 pub fn socket_addr ( & self ) -> io:: Result < SocketAddr > {
197- Err ( io :: Error :: new ( ErrorKind :: Other , "not supported" ) )
223+ Ok ( self . 0 )
198224 }
199225
200226 pub fn accept ( & self ) -> io:: Result < ( TcpStream , SocketAddr ) > {
201- Err ( io:: Error :: new ( ErrorKind :: Other , "not supported" ) )
227+ let ( handle, ipaddr, port) = abi:: tcplistener:: accept ( self . 0 . port ( ) )
228+ . map_err ( |_| io:: Error :: new ( ErrorKind :: Other , "accept failed" ) ) ?;
229+ let saddr = match ipaddr {
230+ Ipv4 ( ref addr) => SocketAddr :: new (
231+ IpAddr :: V4 ( Ipv4Addr :: new ( addr. 0 [ 0 ] , addr. 0 [ 1 ] , addr. 0 [ 2 ] , addr. 0 [ 3 ] ) ) ,
232+ port,
233+ ) ,
234+ Ipv6 ( ref addr) => SocketAddr :: new ( IpAddr :: V6 ( Ipv6Addr :: from ( addr. 0 ) ) , port) ,
235+ _ => {
236+ return Err ( io:: Error :: new ( ErrorKind :: Other , "accept failed" ) ) ;
237+ }
238+ } ;
239+
240+ Ok ( ( TcpStream ( Arc :: new ( Socket ( handle) ) ) , saddr) )
202241 }
203242
204243 pub fn duplicate ( & self ) -> io:: Result < TcpListener > {
205- Err ( io :: Error :: new ( ErrorKind :: Other , "not supported" ) )
244+ Ok ( self . clone ( ) )
206245 }
207246
208247 pub fn set_ttl ( & self , _: u32 ) -> io:: Result < ( ) > {
0 commit comments