@@ -5,9 +5,7 @@ use crate::marker::PhantomData;
55use crate :: mem:: { size_of, zeroed} ;
66use crate :: os:: unix:: io:: RawFd ;
77use 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} ;
119use crate :: slice:: from_raw_parts;
1210use crate :: sys:: net:: Socket ;
1311
@@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from(
3028) -> io:: Result < ( usize , bool , io:: Result < SocketAddr > ) > {
3129 unsafe {
3230 let mut msg_name: libc:: sockaddr_un = zeroed ( ) ;
33-
3431 let mut msg: libc:: msghdr = zeroed ( ) ;
3532 msg. msg_name = & mut msg_name as * mut _ as * mut _ ;
3633 msg. msg_namelen = size_of :: < libc:: sockaddr_un > ( ) as libc:: socklen_t ;
3734 msg. msg_iov = bufs. as_mut_ptr ( ) . cast ( ) ;
38- msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
3935 cfg_if:: cfg_if! {
4036 if #[ cfg( any( target_os = "android" , all( target_os = "linux" , target_env = "gnu" ) ) ) ] {
4137 msg. msg_iovlen = bufs. len( ) as libc:: size_t;
@@ -45,13 +41,18 @@ pub(super) fn recv_vectored_with_ancillary_from(
4541 target_os = "emscripten" ,
4642 target_os = "freebsd" ,
4743 all( target_os = "linux" , target_env = "musl" , ) ,
44+ target_os = "macos" ,
4845 target_os = "netbsd" ,
4946 target_os = "openbsd" ,
5047 ) ) ] {
5148 msg. msg_iovlen = bufs. len( ) as libc:: c_int;
5249 msg. msg_controllen = ancillary. buffer. len( ) as libc:: socklen_t;
5350 }
5451 }
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+ }
5556
5657 let count = socket. recv_msg ( & mut msg) ?;
5758
@@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to(
7980 msg. msg_name = & mut msg_name as * mut _ as * mut _ ;
8081 msg. msg_namelen = msg_namelen;
8182 msg. msg_iov = bufs. as_ptr ( ) as * mut _ ;
82- msg. msg_control = ancillary. buffer . as_mut_ptr ( ) . cast ( ) ;
8383 cfg_if:: cfg_if! {
8484 if #[ cfg( any( target_os = "android" , all( target_os = "linux" , target_env = "gnu" ) ) ) ] {
8585 msg. msg_iovlen = bufs. len( ) as libc:: size_t;
@@ -89,13 +89,18 @@ pub(super) fn send_vectored_with_ancillary_to(
8989 target_os = "emscripten" ,
9090 target_os = "freebsd" ,
9191 all( target_os = "linux" , target_env = "musl" , ) ,
92+ target_os = "macos" ,
9293 target_os = "netbsd" ,
9394 target_os = "openbsd" ,
9495 ) ) ] {
9596 msg. msg_iovlen = bufs. len( ) as libc:: c_int;
9697 msg. msg_controllen = ancillary. length as libc:: socklen_t;
9798 }
9899 }
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+ }
99104
100105 ancillary. truncated = false ;
101106
@@ -147,6 +152,7 @@ fn add_to_ancillary_data<T>(
147152 target_os = "emscripten" ,
148153 target_os = "freebsd" ,
149154 all( target_os = "linux" , target_env = "musl" , ) ,
155+ target_os = "macos" ,
150156 target_os = "netbsd" ,
151157 target_os = "openbsd" ,
152158 ) ) ] {
@@ -159,14 +165,12 @@ fn add_to_ancillary_data<T>(
159165 while !cmsg. is_null ( ) {
160166 previous_cmsg = cmsg;
161167 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 ;
170174 }
171175 }
172176
@@ -184,6 +188,7 @@ fn add_to_ancillary_data<T>(
184188 target_os = "emscripten" ,
185189 target_os = "freebsd" ,
186190 all( target_os = "linux" , target_env = "musl" , ) ,
191+ target_os = "macos" ,
187192 target_os = "netbsd" ,
188193 target_os = "openbsd" ,
189194 ) ) ] {
@@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> {
371376 target_os = "emscripten" ,
372377 target_os = "freebsd" ,
373378 all( target_os = "linux" , target_env = "musl" , ) ,
379+ target_os = "macos" ,
374380 target_os = "netbsd" ,
375381 target_os = "openbsd" ,
376382 ) ) ] {
@@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> {
421427 target_os = "emscripten" ,
422428 target_os = "freebsd" ,
423429 all( target_os = "linux" , target_env = "musl" , ) ,
430+ target_os = "macos" ,
424431 target_os = "netbsd" ,
425432 target_os = "openbsd" ,
426433 ) ) ] {
@@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> {
435442 } ;
436443
437444 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 ;
447452 }
448453 }
449454
@@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> {
514519 self . buffer . len ( )
515520 }
516521
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+
517528 /// Returns the number of used bytes.
518529 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
519530 pub fn len ( & self ) -> usize {
0 commit comments