@@ -85,7 +85,8 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) {
85
85
}
86
86
87
87
88
- use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data} ;
88
+ use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_len, align_of_cmsg_data,
89
+ type_of_msgiov_len, type_of_msg_controllen} ;
89
90
90
91
/// A structure used to make room in a cmsghdr passed to recvmsg. The
91
92
/// size and alignment match that of a cmsghdr followed by a T, but the
@@ -95,8 +96,11 @@ use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data};
95
96
/// To make room for multiple messages, nest the type parameter with
96
97
/// tuples, e.g.
97
98
/// `let cmsg: CmsgSpace<([RawFd; 3], CmsgSpace<[RawFd; 2]>)> = CmsgSpace::new();`
99
+ #[ repr( C ) ]
98
100
pub struct CmsgSpace < T > {
99
101
_hdr : cmsghdr ,
102
+ #[ cfg( not( target_os = "macos" ) ) ]
103
+ _pad : [ align_of_cmsg_data ; 0 ] ,
100
104
_data : T ,
101
105
}
102
106
@@ -156,17 +160,18 @@ impl<'a> Iterator for CmsgIterator<'a> {
156
160
}
157
161
self . 0 = & buf[ cmsg_align ( cmsg_len) ..] ;
158
162
163
+ let cmsg_data = & buf[ cmsg_align ( sizeof_cmsghdr) ..] ;
159
164
match ( cmsg. cmsg_level , cmsg. cmsg_type ) {
160
165
( SOL_SOCKET , SCM_RIGHTS ) => unsafe {
161
166
Some ( ControlMessage :: ScmRights (
162
167
slice:: from_raw_parts (
163
- & cmsg . cmsg_data as * const _ as * const _ , 1 ) ) )
168
+ cmsg_data. as_ptr ( ) as * const _ , 1 ) ) )
164
169
} ,
165
170
( _, _) => unsafe {
166
171
Some ( ControlMessage :: Unknown ( UnknownCmsg (
167
172
& cmsg,
168
173
slice:: from_raw_parts (
169
- & cmsg . cmsg_data as * const _ as * const _ ,
174
+ cmsg_data. as_ptr ( ) as * const _ ,
170
175
len) ) ) )
171
176
}
172
177
}
@@ -191,7 +196,7 @@ pub enum ControlMessage<'a> {
191
196
pub struct UnknownCmsg < ' a > ( & ' a cmsghdr , & ' a [ u8 ] ) ;
192
197
193
198
fn cmsg_align ( len : usize ) -> usize {
194
- let align_bytes = mem:: size_of :: < type_of_cmsg_data > ( ) - 1 ;
199
+ let align_bytes = mem:: size_of :: < align_of_cmsg_data > ( ) - 1 ;
195
200
( len + align_bytes) & !align_bytes
196
201
}
197
202
@@ -213,8 +218,8 @@ impl<'a> ControlMessage<'a> {
213
218
}
214
219
}
215
220
216
- // Unsafe: start and end of buffer must be size_t-aligned (that is,
217
- // cmsg_align'd). Updates the provided slice; panics if the buffer
221
+ // Unsafe: start and end of buffer must be cmsg_align'd.
222
+ // Updates the provided slice; panics if the buffer
218
223
// is too small.
219
224
unsafe fn encode_into < ' b > ( & self , buf : & mut & ' b mut [ u8 ] ) {
220
225
match * self {
@@ -223,7 +228,6 @@ impl<'a> ControlMessage<'a> {
223
228
cmsg_len : self . len ( ) as type_of_cmsg_len ,
224
229
cmsg_level : SOL_SOCKET ,
225
230
cmsg_type : SCM_RIGHTS ,
226
- cmsg_data : [ ] ,
227
231
} ;
228
232
copy_bytes ( & cmsg, buf) ;
229
233
@@ -287,9 +291,9 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
287
291
msg_name : name as * const c_void ,
288
292
msg_namelen : namelen,
289
293
msg_iov : iov. as_ptr ( ) ,
290
- msg_iovlen : iov. len ( ) as size_t ,
294
+ msg_iovlen : iov. len ( ) as type_of_msgiov_len ,
291
295
msg_control : cmsg_ptr,
292
- msg_controllen : capacity as size_t ,
296
+ msg_controllen : capacity as type_of_msg_controllen ,
293
297
msg_flags : 0 ,
294
298
} ;
295
299
let ret = unsafe { ffi:: sendmsg ( fd, & mhdr, flags. bits ( ) ) } ;
@@ -310,9 +314,9 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
310
314
msg_name : & mut address as * const _ as * const c_void ,
311
315
msg_namelen : mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ,
312
316
msg_iov : iov. as_ptr ( ) as * const IoVec < & [ u8 ] > , // safe cast to add const-ness
313
- msg_iovlen : iov. len ( ) as size_t ,
317
+ msg_iovlen : iov. len ( ) as type_of_msgiov_len ,
314
318
msg_control : msg_control as * const c_void ,
315
- msg_controllen : msg_controllen as size_t ,
319
+ msg_controllen : msg_controllen as type_of_msg_controllen ,
316
320
msg_flags : 0 ,
317
321
} ;
318
322
let ret = unsafe { ffi:: recvmsg ( fd, & mut mhdr, flags. bits ( ) ) } ;
@@ -692,6 +696,8 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
692
696
693
697
#[ test]
694
698
pub fn test_struct_sizes ( ) {
695
- use nixtest;
696
- nixtest:: assert_size_of :: < sockaddr_storage > ( "sockaddr_storage" ) ;
699
+ use nixtest:: assert_size_of;
700
+ assert_size_of :: < sockaddr_storage > ( "sockaddr_storage" ) ;
701
+ assert_size_of :: < msghdr > ( "msghdr" ) ;
702
+ assert_size_of :: < cmsghdr > ( "cmsghdr" ) ;
697
703
}
0 commit comments