@@ -55,9 +55,18 @@ impl Socket {
5555 pub fn new_raw ( fam : c_int , ty : c_int ) -> io:: Result < Socket > {
5656 unsafe {
5757 cfg_if:: cfg_if! {
58- if #[ cfg( target_os = "linux" ) ] {
59- // On Linux we pass the SOCK_CLOEXEC flag to atomically create
60- // the socket and set it as CLOEXEC, added in 2.6.27.
58+ if #[ cfg( any(
59+ target_os = "android" ,
60+ target_os = "dragonfly" ,
61+ target_os = "freebsd" ,
62+ target_os = "illumos" ,
63+ target_os = "linux" ,
64+ target_os = "netbsd" ,
65+ target_os = "opensbd" ,
66+ ) ) ] {
67+ // On platforms that support it we pass the SOCK_CLOEXEC
68+ // flag to atomically create the socket and set it as
69+ // CLOEXEC. On Linux this was added in 2.6.27.
6170 let fd = cvt( libc:: socket( fam, ty | libc:: SOCK_CLOEXEC , 0 ) ) ?;
6271 Ok ( Socket ( FileDesc :: new( fd) ) )
6372 } else {
@@ -83,7 +92,15 @@ impl Socket {
8392 let mut fds = [ 0 , 0 ] ;
8493
8594 cfg_if:: cfg_if! {
86- if #[ cfg( target_os = "linux" ) ] {
95+ if #[ cfg( any(
96+ target_os = "android" ,
97+ target_os = "dragonfly" ,
98+ target_os = "freebsd" ,
99+ target_os = "illumos" ,
100+ target_os = "linux" ,
101+ target_os = "netbsd" ,
102+ target_os = "opensbd" ,
103+ ) ) ] {
87104 // Like above, set cloexec atomically
88105 cvt( libc:: socketpair( fam, ty | libc:: SOCK_CLOEXEC , 0 , fds. as_mut_ptr( ) ) ) ?;
89106 Ok ( ( Socket ( FileDesc :: new( fds[ 0 ] ) ) , Socket ( FileDesc :: new( fds[ 1 ] ) ) ) )
@@ -174,13 +191,28 @@ impl Socket {
174191 pub fn accept ( & self , storage : * mut sockaddr , len : * mut socklen_t ) -> io:: Result < Socket > {
175192 // Unfortunately the only known way right now to accept a socket and
176193 // atomically set the CLOEXEC flag is to use the `accept4` syscall on
177- // Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5.
194+ // platforms that support it. On Linux, this was added in 2.6.28,
195+ // glibc 2.10 and musl 0.9.5.
178196 cfg_if:: cfg_if! {
179- if #[ cfg( target_os = "linux" ) ] {
197+ if #[ cfg( any(
198+ target_os = "dragonfly" ,
199+ target_os = "freebsd" ,
200+ target_os = "illumos" ,
201+ target_os = "linux" ,
202+ target_os = "netbsd" ,
203+ target_os = "opensbd" ,
204+ ) ) ] {
180205 let fd = cvt_r( || unsafe {
181206 libc:: accept4( self . 0 . raw( ) , storage, len, libc:: SOCK_CLOEXEC )
182207 } ) ?;
183208 Ok ( Socket ( FileDesc :: new( fd) ) )
209+ // While the Android kernel supports the syscall,
210+ // it is not included in all versions of Android's libc.
211+ } else if #[ cfg( target_os = "android" ) ] {
212+ let fd = cvt_r( || unsafe {
213+ libc:: syscall( libc:: SYS_accept4 , self . 0 . raw( ) , storage, len, libc:: SOCK_CLOEXEC )
214+ } ) ?;
215+ Ok ( Socket ( FileDesc :: new( fd as c_int) ) )
184216 } else {
185217 let fd = cvt_r( || unsafe { libc:: accept( self . 0 . raw( ) , storage, len) } ) ?;
186218 let fd = FileDesc :: new( fd) ;
0 commit comments