@@ -5,9 +5,7 @@ use crate::marker::PhantomData;
5
5
use crate :: mem:: { size_of, zeroed} ;
6
6
use crate :: os:: unix:: io:: RawFd ;
7
7
use crate :: path:: Path ;
8
- #[ cfg( target_os = "android" ) ]
9
- use crate :: ptr:: eq;
10
- use crate :: ptr:: read_unaligned;
8
+ use crate :: ptr:: { eq, read_unaligned} ;
11
9
use crate :: slice:: from_raw_parts;
12
10
use crate :: sys:: net:: Socket ;
13
11
@@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from(
30
28
) -> io:: Result < ( usize , bool , io:: Result < SocketAddr > ) > {
31
29
unsafe {
32
30
let mut msg_name: libc:: sockaddr_un = zeroed ( ) ;
33
-
34
31
let mut msg: libc:: msghdr = zeroed ( ) ;
35
32
msg. msg_name = & mut msg_name as * mut _ as * mut _ ;
36
33
msg. msg_namelen = size_of :: < libc:: sockaddr_un > ( ) as libc:: socklen_t ;
37
34
msg. msg_iov = bufs. as_mut_ptr ( ) . cast ( ) ;
38
- msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
39
35
cfg_if:: cfg_if! {
40
36
if #[ cfg( any( target_os = "android" , all( target_os = "linux" , target_env = "gnu" ) ) ) ] {
41
37
msg. msg_iovlen = bufs. len( ) as libc:: size_t;
@@ -45,13 +41,18 @@ pub(super) fn recv_vectored_with_ancillary_from(
45
41
target_os = "emscripten" ,
46
42
target_os = "freebsd" ,
47
43
all( target_os = "linux" , target_env = "musl" , ) ,
44
+ target_os = "macos" ,
48
45
target_os = "netbsd" ,
49
46
target_os = "openbsd" ,
50
47
) ) ] {
51
48
msg. msg_iovlen = bufs. len( ) as libc:: c_int;
52
49
msg. msg_controllen = ancillary. buffer. len( ) as libc:: socklen_t;
53
50
}
54
51
}
52
+ // macos requires that the control pointer is NULL when the len is 0.
53
+ if msg. msg_controllen > 0 {
54
+ msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
55
+ }
55
56
56
57
let count = socket. recv_msg ( & mut msg) ?;
57
58
@@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to(
79
80
msg. msg_name = & mut msg_name as * mut _ as * mut _ ;
80
81
msg. msg_namelen = msg_namelen;
81
82
msg. msg_iov = bufs. as_ptr ( ) as * mut _ ;
82
- msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
83
83
cfg_if:: cfg_if! {
84
84
if #[ cfg( any( target_os = "android" , all( target_os = "linux" , target_env = "gnu" ) ) ) ] {
85
85
msg. msg_iovlen = bufs. len( ) as libc:: size_t;
@@ -89,13 +89,18 @@ pub(super) fn send_vectored_with_ancillary_to(
89
89
target_os = "emscripten" ,
90
90
target_os = "freebsd" ,
91
91
all( target_os = "linux" , target_env = "musl" , ) ,
92
+ target_os = "macos" ,
92
93
target_os = "netbsd" ,
93
94
target_os = "openbsd" ,
94
95
) ) ] {
95
96
msg. msg_iovlen = bufs. len( ) as libc:: c_int;
96
97
msg. msg_controllen = ancillary. length as libc:: socklen_t;
97
98
}
98
99
}
100
+ // macos requires that the control pointer is NULL when the len is 0.
101
+ if msg. msg_controllen > 0 {
102
+ msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
103
+ }
99
104
100
105
ancillary. truncated = false ;
101
106
@@ -147,6 +152,7 @@ fn add_to_ancillary_data<T>(
147
152
target_os = "emscripten" ,
148
153
target_os = "freebsd" ,
149
154
all( target_os = "linux" , target_env = "musl" , ) ,
155
+ target_os = "macos" ,
150
156
target_os = "netbsd" ,
151
157
target_os = "openbsd" ,
152
158
) ) ] {
@@ -159,14 +165,12 @@ fn add_to_ancillary_data<T>(
159
165
while !cmsg. is_null ( ) {
160
166
previous_cmsg = cmsg;
161
167
cmsg = libc:: CMSG_NXTHDR ( & msg, cmsg) ;
162
- cfg_if:: cfg_if! {
163
- // Android return the same pointer if it is the last cmsg.
164
- // Therefore, check it if the previous pointer is the same as the current one.
165
- if #[ cfg( target_os = "android" ) ] {
166
- if cmsg == previous_cmsg {
167
- break ;
168
- }
169
- }
168
+
169
+ // Most operating systems, but not Linux or emscripten, return the previous pointer
170
+ // when its length is zero. Therefore, check if the previous pointer is the same as
171
+ // the current one.
172
+ if eq ( cmsg, previous_cmsg) {
173
+ break ;
170
174
}
171
175
}
172
176
@@ -184,6 +188,7 @@ fn add_to_ancillary_data<T>(
184
188
target_os = "emscripten" ,
185
189
target_os = "freebsd" ,
186
190
all( target_os = "linux" , target_env = "musl" , ) ,
191
+ target_os = "macos" ,
187
192
target_os = "netbsd" ,
188
193
target_os = "openbsd" ,
189
194
) ) ] {
@@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> {
371
376
target_os = "emscripten" ,
372
377
target_os = "freebsd" ,
373
378
all( target_os = "linux" , target_env = "musl" , ) ,
379
+ target_os = "macos" ,
374
380
target_os = "netbsd" ,
375
381
target_os = "openbsd" ,
376
382
) ) ] {
@@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> {
421
427
target_os = "emscripten" ,
422
428
target_os = "freebsd" ,
423
429
all( target_os = "linux" , target_env = "musl" , ) ,
430
+ target_os = "macos" ,
424
431
target_os = "netbsd" ,
425
432
target_os = "openbsd" ,
426
433
) ) ] {
@@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> {
435
442
} ;
436
443
437
444
let cmsg = cmsg. as_ref ( ) ?;
438
- cfg_if:: cfg_if! {
439
- // Android return the same pointer if it is the last cmsg.
440
- // Therefore, check it if the previous pointer is the same as the current one.
441
- if #[ cfg( target_os = "android" ) ] {
442
- if let Some ( current) = self . current {
443
- if eq( current, cmsg) {
444
- return None ;
445
- }
446
- }
445
+
446
+ // Most operating systems, but not Linux or emscripten, return the previous pointer
447
+ // when its length is zero. Therefore, check if the previous pointer is the same as
448
+ // the current one.
449
+ if let Some ( current) = self . current {
450
+ if eq ( current, cmsg) {
451
+ return None ;
447
452
}
448
453
}
449
454
@@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> {
514
519
self . buffer . len ( )
515
520
}
516
521
522
+ /// Returns `true` if the ancillary data is empty.
523
+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
524
+ pub fn is_empty ( & self ) -> bool {
525
+ self . length == 0
526
+ }
527
+
517
528
/// Returns the number of used bytes.
518
529
#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
519
530
pub fn len ( & self ) -> usize {
0 commit comments