@@ -261,21 +261,6 @@ impl Ipv6MembershipRequest {
261
261
}
262
262
}
263
263
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
-
279
264
/// Create a buffer large enough for storing some control messages as returned
280
265
/// by [`recvmsg`](fn.recvmsg.html).
281
266
///
@@ -311,63 +296,11 @@ macro_rules! cmsg_space {
311
296
CMSG_SPACE ( mem:: size_of:: <$x>( ) as c_uint)
312
297
} as usize ;
313
298
) *
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)
318
300
}
319
301
}
320
302
}
321
303
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
-
371
304
#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
372
305
pub struct RecvMsg < ' a > {
373
306
pub bytes : usize ,
@@ -893,33 +826,39 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
893
826
/// optionally receive ancillary data into the provided buffer.
894
827
/// If no ancillary data is desired, use () as the type parameter.
895
828
///
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
+ ///
896
837
/// # References
897
838
/// [recvmsg(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
898
839
pub 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 > > ,
900
841
flags : MsgFlags ) -> Result < RecvMsg < ' a > >
901
842
{
902
843
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
+ }
923
862
} ;
924
863
925
864
let ret = unsafe { libc:: recvmsg ( fd, & mut mhdr, flags. bits ( ) ) } ;
@@ -928,6 +867,10 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
928
867
let cmsghdr = unsafe {
929
868
if mhdr. msg_controllen > 0 {
930
869
// got control message(s)
870
+ cmsg_buffer
871
+ . as_mut ( )
872
+ . unwrap ( )
873
+ . set_len ( mhdr. msg_controllen as usize ) ;
931
874
debug_assert ! ( !mhdr. msg_control. is_null( ) ) ;
932
875
debug_assert ! ( msg_controllen >= mhdr. msg_controllen as usize ) ;
933
876
CMSG_FIRSTHDR ( & mhdr as * const msghdr )
0 commit comments