File tree 2 files changed +40
-2
lines changed
2 files changed +40
-2
lines changed Original file line number Diff line number Diff line change @@ -1818,4 +1818,31 @@ mod tests {
1818
1818
let addr = listener. local_addr ( ) . unwrap ( ) ;
1819
1819
TcpStream :: connect_timeout ( & addr, Duration :: from_secs ( 2 ) ) . unwrap ( ) ;
1820
1820
}
1821
+
1822
+ #[ test]
1823
+ fn nonblocking_accept ( ) {
1824
+ let socket_addr = next_test_ip4 ( ) ;
1825
+ let listener = t ! ( TcpListener :: bind( & socket_addr) ) ;
1826
+ t ! ( listener. set_nonblocking( true ) ) ;
1827
+
1828
+ let _t = thread:: spawn ( move || {
1829
+ t ! ( TcpStream :: connect( & ( "localhost" , socket_addr. port( ) ) ) ) ;
1830
+ thread:: sleep ( Duration :: from_millis ( 1000 ) ) ;
1831
+ } ) ;
1832
+
1833
+ loop {
1834
+ match listener. accept ( ) {
1835
+ Ok ( ( mut stream, _) ) => {
1836
+ let mut buf = [ 0 ; 2 ] ;
1837
+ match stream. read_exact ( & mut buf) {
1838
+ Ok ( _) => panic ! ( "expected error" ) ,
1839
+ Err ( ref e) if e. kind ( ) == ErrorKind :: WouldBlock => return ,
1840
+ Err ( e) => panic ! ( "unexpected error {:?}" , e) ,
1841
+ }
1842
+ }
1843
+ Err ( e) if e. kind ( ) == ErrorKind :: WouldBlock => { }
1844
+ Err ( e) => panic ! ( "unexpected error {:?}" , e) ,
1845
+ }
1846
+ }
1847
+ }
1821
1848
}
Original file line number Diff line number Diff line change @@ -189,7 +189,14 @@ impl Socket {
189
189
flags: c_int
190
190
) -> c_int
191
191
}
192
- let res = cvt_r ( || unsafe { accept4 ( self . 0 . raw ( ) , storage, len, libc:: SOCK_CLOEXEC ) } ) ;
192
+ let is_blocking =
193
+ unsafe { ( cvt ( libc:: fcntl ( self . 0 . raw ( ) , libc:: F_GETFL ) ) ? & libc:: O_NONBLOCK ) != 0 } ;
194
+ let accept_flags = if is_blocking {
195
+ libc:: SOCK_CLOEXEC | libc:: SOCK_NONBLOCK
196
+ } else {
197
+ libc:: SOCK_CLOEXEC
198
+ } ;
199
+ let res = cvt_r ( || unsafe { accept4 ( self . 0 . raw ( ) , storage, len, accept_flags) } ) ;
193
200
match res {
194
201
Ok ( fd) => return Ok ( Socket ( FileDesc :: new ( fd) ) ) ,
195
202
Err ( ref e) if e. raw_os_error ( ) == Some ( libc:: ENOSYS ) => { }
@@ -329,7 +336,11 @@ impl Socket {
329
336
330
337
pub fn take_error ( & self ) -> io:: Result < Option < io:: Error > > {
331
338
let raw: c_int = getsockopt ( self , libc:: SOL_SOCKET , libc:: SO_ERROR ) ?;
332
- if raw == 0 { Ok ( None ) } else { Ok ( Some ( io:: Error :: from_raw_os_error ( raw as i32 ) ) ) }
339
+ if raw == 0 {
340
+ Ok ( None )
341
+ } else {
342
+ Ok ( Some ( io:: Error :: from_raw_os_error ( raw as i32 ) ) )
343
+ }
333
344
}
334
345
}
335
346
You can’t perform that action at this time.
0 commit comments