22
33use std:: ffi:: c_void;
44use std:: os:: fd:: RawFd ;
5- use std:: { io, mem} ;
5+ use std:: { io, mem, ptr } ;
66
77// Yes, really. cmsg components are aligned to [libc::c_long]
88pub ( crate ) struct Cmsg < const N : usize > {
@@ -15,9 +15,8 @@ impl<const N: usize> Cmsg<N> {
1515 pub ( crate ) fn new ( level : i32 , typ : i32 , data : [ u8 ; N ] ) -> Self {
1616 Self {
1717 hdr : libc:: cmsghdr {
18- // on Linux this is a usize, on macOS this is a u32
19- #[ allow( clippy:: unnecessary_cast) ]
20- cmsg_len : ( mem:: offset_of!( Self , data) + N ) as _ ,
18+ // on Linux this is a usize
19+ cmsg_len : mem:: offset_of!( Self , data) + N ,
2120 cmsg_level : level,
2221 cmsg_type : typ,
2322 } ,
@@ -42,24 +41,29 @@ impl<const N: usize> Cmsg<N> {
4241/// A wrapper around [`libc::sendmsg`].
4342pub ( crate ) fn sendmsg < const N : usize > (
4443 fd : RawFd ,
45- data : & [ io:: IoSlice < ' _ > ] ,
44+ data : & mut [ io:: IoSlice < ' _ > ] ,
4645 cmsg : Option < & Cmsg < N > > ,
4746 flags : i32 ,
4847) -> io:: Result < usize > {
49- let mut msg: libc:: msghdr = unsafe { std:: mem:: zeroed ( ) } ;
48+ #[ allow( unsafe_code) ]
49+ // SAFETY: zeroed is fine for msghdr as we will set all the fields we use.
50+ let mut msg: libc:: msghdr = unsafe { mem:: zeroed ( ) } ;
5051
5152 if let Some ( cmsg) = cmsg {
52- msg. msg_control = cmsg as * const _ as * mut c_void ;
53- msg. msg_controllen = std :: mem :: size_of_val ( cmsg) ;
53+ msg. msg_control = ptr :: from_ref ( cmsg) as * mut c_void ;
54+ msg. msg_controllen = size_of_val ( cmsg) ;
5455 }
5556
56- msg. msg_iov = data. as_ptr ( ) as * const _ as * mut libc :: iovec ;
57+ msg. msg_iov = ptr :: from_mut ( data) . cast ( ) ;
5758 msg. msg_iovlen = data. len ( ) ;
5859
60+ #[ allow( unsafe_code) ]
61+ // SAFETY: syscall
5962 let ret = unsafe { libc:: sendmsg ( fd, & msg, flags) } ;
6063 match ret {
61- -1 => Err ( io:: Error :: last_os_error ( ) ) ,
62- len => Ok ( len as usize ) ,
64+ ..0 => Err ( io:: Error :: last_os_error ( ) ) ,
65+ #[ allow( clippy:: cast_sign_loss) ]
66+ len @ 0 .. => Ok ( len as usize ) ,
6367 }
6468}
6569
@@ -79,10 +83,13 @@ pub(crate) fn recvmsg_whole<const N: usize>(
7983 }
8084
8185 loop {
82- let mut msg: libc:: msghdr = unsafe { std:: mem:: zeroed ( ) } ;
86+ #[ allow( unsafe_code) ]
87+ // SAFETY: zeroed is fine for msghdr as we will set all the fields we use.
88+ let mut msg: libc:: msghdr = unsafe { mem:: zeroed ( ) } ;
89+
8390 if let Some ( cmsg) = cmsg. as_deref_mut ( ) {
84- msg. msg_control = cmsg as * mut _ as * mut c_void ;
85- msg. msg_controllen = std :: mem :: size_of_val ( cmsg) ;
91+ msg. msg_control = ptr :: from_mut ( cmsg) . cast ( ) ;
92+ msg. msg_controllen = size_of_val ( cmsg) ;
8693 }
8794
8895 if data. spare_capacity_mut ( ) . is_empty ( ) {
@@ -91,23 +98,28 @@ pub(crate) fn recvmsg_whole<const N: usize>(
9198
9299 let spare = data. spare_capacity_mut ( ) ;
93100 let mut iov = libc:: iovec {
94- iov_base : spare. as_mut_ptr ( ) as * mut c_void ,
101+ iov_base : spare. as_mut_ptr ( ) . cast ( ) ,
95102 iov_len : spare. len ( ) ,
96103 } ;
97104
98105 msg. msg_iov = & mut iov;
99106 msg. msg_iovlen = 1 ;
100107
108+ #[ allow( unsafe_code) ]
101109 // SAFETY: We have made sure to initialize msg with valid pointers (or NULL).
102110 let ret = unsafe { libc:: recvmsg ( fd, & mut msg, flags) } ;
103111 let count = match ret {
104- -1 => return Err ( io:: Error :: last_os_error ( ) ) ,
105- len => len as usize ,
112+ ..0 => return Err ( io:: Error :: last_os_error ( ) ) ,
113+ #[ allow( clippy:: cast_sign_loss) ]
114+ len @ 0 .. => len as usize ,
106115 } ;
107116
117+ #[ allow( unsafe_code) ]
108118 // SAFETY: recvmsg has just written count to the bytes in the spare capacity of
109119 // the vector.
110- unsafe { data. set_len ( data. len ( ) + count) } ;
120+ unsafe {
121+ data. set_len ( data. len ( ) + count) ;
122+ } ;
111123
112124 if msg. msg_flags & libc:: MSG_EOR != 0 {
113125 break Ok ( msg. msg_flags ) ;
0 commit comments