@@ -261,21 +261,6 @@ impl Ipv6MembershipRequest {
261261 }
262262}
263263
264- cfg_if ! {
265- // Darwin and DragonFly BSD always align struct cmsghdr to 32-bit only.
266- if #[ cfg( any( target_os = "dragonfly" , target_os = "ios" , target_os = "macos" ) ) ] {
267- type align_of_cmsg_data = u32 ;
268- } else {
269- type align_of_cmsg_data = size_t;
270- }
271- }
272-
273- /// A type that can be used to store ancillary data received by
274- /// [`recvmsg`](fn.recvmsg.html)
275- pub trait CmsgBuffer {
276- fn as_bytes_mut ( & mut self ) -> & mut [ u8 ] ;
277- }
278-
279264/// Create a buffer large enough for storing some control messages as returned
280265/// by [`recvmsg`](fn.recvmsg.html).
281266///
@@ -311,63 +296,11 @@ macro_rules! cmsg_space {
311296 CMSG_SPACE ( mem:: size_of:: <$x>( ) as c_uint)
312297 } as usize ;
313298 ) *
314- let mut v = Vec :: <u8 >:: with_capacity( space) ;
315- // safe because any bit pattern is a valid u8
316- unsafe { v. set_len( space) } ;
317- v
299+ Vec :: <u8 >:: with_capacity( space)
318300 }
319301 }
320302}
321303
322- /// A structure used to make room in a cmsghdr passed to recvmsg. The
323- /// size and alignment match that of a cmsghdr followed by a T, but the
324- /// fields are not accessible, as the actual types will change on a call
325- /// to recvmsg.
326- ///
327- /// To make room for multiple messages, nest the type parameter with
328- /// tuples:
329- ///
330- /// ```
331- /// use std::os::unix::io::RawFd;
332- /// use nix::sys::socket::CmsgSpace;
333- /// let cmsg: CmsgSpace<([RawFd; 3], CmsgSpace<[RawFd; 2]>)> = CmsgSpace::new();
334- /// ```
335- #[ repr( C ) ]
336- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
337- pub struct CmsgSpace < T > {
338- _hdr : cmsghdr ,
339- _pad : [ align_of_cmsg_data ; 0 ] ,
340- _data : T ,
341- }
342-
343- impl < T > CmsgSpace < T > {
344- /// Create a CmsgSpace<T>. The structure is used only for space, so
345- /// the fields are uninitialized.
346- #[ deprecated( since="0.14.0" , note="Use the cmsg_space! macro instead" ) ]
347- // It's deprecated anyway; no sense adding Default
348- #[ allow( clippy:: new_without_default) ]
349- pub fn new ( ) -> Self {
350- // Safe because the fields themselves aren't accessible.
351- unsafe { mem:: uninitialized ( ) }
352- }
353- }
354-
355- impl < T > CmsgBuffer for CmsgSpace < T > {
356- fn as_bytes_mut ( & mut self ) -> & mut [ u8 ] {
357- // Safe because nothing ever attempts to access CmsgSpace's fields
358- unsafe {
359- slice:: from_raw_parts_mut ( self as * mut CmsgSpace < T > as * mut u8 ,
360- mem:: size_of :: < Self > ( ) )
361- }
362- }
363- }
364-
365- impl CmsgBuffer for Vec < u8 > {
366- fn as_bytes_mut ( & mut self ) -> & mut [ u8 ] {
367- & mut self [ ..]
368- }
369- }
370-
371304#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
372305pub struct RecvMsg < ' a > {
373306 pub bytes : usize ,
@@ -893,33 +826,39 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
893826/// optionally receive ancillary data into the provided buffer.
894827/// If no ancillary data is desired, use () as the type parameter.
895828///
829+ /// # Arguments
830+ ///
831+ /// * `fd`: Socket file descriptor
832+ /// * `iov`: Scatter-gather list of buffers to receive the message
833+ /// * `cmsg_buffer`: Space to receive ancillary data. Should be created by
834+ /// [`cmsg_space!`](macro.cmsg_space.html)
835+ /// * `flags`: Optional flags passed directly to the operating system.
836+ ///
896837/// # References
897838/// [recvmsg(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
898839pub fn recvmsg < ' a > ( fd : RawFd , iov : & [ IoVec < & mut [ u8 ] > ] ,
899- cmsg_buffer : Option < & ' a mut dyn CmsgBuffer > ,
840+ mut cmsg_buffer : Option < & ' a mut Vec < u8 > > ,
900841 flags : MsgFlags ) -> Result < RecvMsg < ' a > >
901842{
902843 let mut address = mem:: MaybeUninit :: uninit ( ) ;
903- let ( msg_control, msg_controllen) = match cmsg_buffer {
904- Some ( cmsgspace) => {
905- let msg_buf = cmsgspace. as_bytes_mut ( ) ;
906- ( msg_buf. as_mut_ptr ( ) , msg_buf. len ( ) )
907- } ,
908- None => ( ptr:: null_mut ( ) , 0 ) ,
909- } ;
910- let mut mhdr = unsafe {
911- // Musl's msghdr has private fields, so this is the only way to
912- // initialize it.
913- let mut mhdr = mem:: MaybeUninit :: < msghdr > :: zeroed ( ) ;
914- let p = mhdr. as_mut_ptr ( ) ;
915- ( * p) . msg_name = address. as_mut_ptr ( ) as * mut c_void ;
916- ( * p) . msg_namelen = mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ;
917- ( * p) . msg_iov = iov. as_ptr ( ) as * mut iovec ;
918- ( * p) . msg_iovlen = iov. len ( ) as _ ;
919- ( * p) . msg_control = msg_control as * mut c_void ;
920- ( * p) . msg_controllen = msg_controllen as _ ;
921- ( * p) . msg_flags = 0 ;
922- mhdr. assume_init ( )
844+ let ( msg_control, msg_controllen) = cmsg_buffer. as_mut ( )
845+ . map ( |v| ( v. as_mut_ptr ( ) , v. capacity ( ) ) )
846+ . unwrap_or ( ( ptr:: null_mut ( ) , 0 ) ) ;
847+ let mut mhdr = {
848+ unsafe {
849+ // Musl's msghdr has private fields, so this is the only way to
850+ // initialize it.
851+ let mut mhdr = mem:: MaybeUninit :: < msghdr > :: zeroed ( ) ;
852+ let p = mhdr. as_mut_ptr ( ) ;
853+ ( * p) . msg_name = address. as_mut_ptr ( ) as * mut c_void ;
854+ ( * p) . msg_namelen = mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ;
855+ ( * p) . msg_iov = iov. as_ptr ( ) as * mut iovec ;
856+ ( * p) . msg_iovlen = iov. len ( ) as _ ;
857+ ( * p) . msg_control = msg_control as * mut c_void ;
858+ ( * p) . msg_controllen = msg_controllen as _ ;
859+ ( * p) . msg_flags = 0 ;
860+ mhdr. assume_init ( )
861+ }
923862 } ;
924863
925864 let ret = unsafe { libc:: recvmsg ( fd, & mut mhdr, flags. bits ( ) ) } ;
@@ -928,6 +867,10 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
928867 let cmsghdr = unsafe {
929868 if mhdr. msg_controllen > 0 {
930869 // got control message(s)
870+ cmsg_buffer
871+ . as_mut ( )
872+ . unwrap ( )
873+ . set_len ( mhdr. msg_controllen as usize ) ;
931874 debug_assert ! ( !mhdr. msg_control. is_null( ) ) ;
932875 debug_assert ! ( msg_controllen >= mhdr. msg_controllen as usize ) ;
933876 CMSG_FIRSTHDR ( & mhdr as * const msghdr )
0 commit comments