File tree Expand file tree Collapse file tree 2 files changed +40
-2
lines changed
Expand file tree Collapse file tree 2 files changed +40
-2
lines changed Original file line number Diff line number Diff line change @@ -1818,4 +1818,31 @@ mod tests {
18181818 let addr = listener. local_addr ( ) . unwrap ( ) ;
18191819 TcpStream :: connect_timeout ( & addr, Duration :: from_secs ( 2 ) ) . unwrap ( ) ;
18201820 }
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+ }
18211848}
Original file line number Diff line number Diff line change @@ -189,7 +189,14 @@ impl Socket {
189189 flags: c_int
190190 ) -> c_int
191191 }
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) } ) ;
193200 match res {
194201 Ok ( fd) => return Ok ( Socket ( FileDesc :: new ( fd) ) ) ,
195202 Err ( ref e) if e. raw_os_error ( ) == Some ( libc:: ENOSYS ) => { }
@@ -329,7 +336,11 @@ impl Socket {
329336
330337 pub fn take_error ( & self ) -> io:: Result < Option < io:: Error > > {
331338 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+ }
333344 }
334345}
335346
You can’t perform that action at this time.
0 commit comments