@@ -55,9 +55,18 @@ impl Socket {
55
55
pub fn new_raw ( fam : c_int , ty : c_int ) -> io:: Result < Socket > {
56
56
unsafe {
57
57
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.
61
70
let fd = cvt( libc:: socket( fam, ty | libc:: SOCK_CLOEXEC , 0 ) ) ?;
62
71
Ok ( Socket ( FileDesc :: new( fd) ) )
63
72
} else {
@@ -83,7 +92,15 @@ impl Socket {
83
92
let mut fds = [ 0 , 0 ] ;
84
93
85
94
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
+ ) ) ] {
87
104
// Like above, set cloexec atomically
88
105
cvt( libc:: socketpair( fam, ty | libc:: SOCK_CLOEXEC , 0 , fds. as_mut_ptr( ) ) ) ?;
89
106
Ok ( ( Socket ( FileDesc :: new( fds[ 0 ] ) ) , Socket ( FileDesc :: new( fds[ 1 ] ) ) ) )
@@ -174,13 +191,28 @@ impl Socket {
174
191
pub fn accept ( & self , storage : * mut sockaddr , len : * mut socklen_t ) -> io:: Result < Socket > {
175
192
// Unfortunately the only known way right now to accept a socket and
176
193
// 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.
178
196
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
+ ) ) ] {
180
205
let fd = cvt_r( || unsafe {
181
206
libc:: accept4( self . 0 . raw( ) , storage, len, libc:: SOCK_CLOEXEC )
182
207
} ) ?;
183
208
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) ) )
184
216
} else {
185
217
let fd = cvt_r( || unsafe { libc:: accept( self . 0 . raw( ) , storage, len) } ) ?;
186
218
let fd = FileDesc :: new( fd) ;
0 commit comments