@@ -168,7 +168,7 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) {
168
168
}
169
169
170
170
171
- use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_len , type_of_cmsg_data } ;
171
+ use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_data , type_of_msg_iovlen , type_of_cmsg_len } ;
172
172
173
173
/// A structure used to make room in a cmsghdr passed to recvmsg. The
174
174
/// size and alignment match that of a cmsghdr followed by a T, but the
@@ -204,11 +204,17 @@ impl<'a> RecvMsg<'a> {
204
204
/// Iterate over the valid control messages pointed to by this
205
205
/// msghdr.
206
206
pub fn cmsgs ( & self ) -> CmsgIterator {
207
- CmsgIterator ( self . cmsg_buffer )
207
+ CmsgIterator {
208
+ buf : self . cmsg_buffer ,
209
+ next : 0
210
+ }
208
211
}
209
212
}
210
213
211
- pub struct CmsgIterator < ' a > ( & ' a [ u8 ] ) ;
214
+ pub struct CmsgIterator < ' a > {
215
+ buf : & ' a [ u8 ] ,
216
+ next : usize ,
217
+ }
212
218
213
219
impl < ' a > Iterator for CmsgIterator < ' a > {
214
220
type Item = ControlMessage < ' a > ;
@@ -217,12 +223,11 @@ impl<'a> Iterator for CmsgIterator<'a> {
217
223
// although we handle the invariants in slightly different places to
218
224
// get a better iterator interface.
219
225
fn next ( & mut self ) -> Option < ControlMessage < ' a > > {
220
- let buf = self . 0 ;
221
226
let sizeof_cmsghdr = mem:: size_of :: < cmsghdr > ( ) ;
222
- if buf. len ( ) < sizeof_cmsghdr {
227
+ if self . buf . len ( ) < sizeof_cmsghdr {
223
228
return None ;
224
229
}
225
- let cmsg: & cmsghdr = unsafe { mem:: transmute ( buf. as_ptr ( ) ) } ;
230
+ let cmsg: & cmsghdr = unsafe { mem:: transmute ( self . buf . as_ptr ( ) ) } ;
226
231
227
232
// This check is only in the glibc implementation of CMSG_NXTHDR
228
233
// (although it claims the kernel header checks this), but such
@@ -232,12 +237,20 @@ impl<'a> Iterator for CmsgIterator<'a> {
232
237
return None ;
233
238
}
234
239
let len = cmsg_len - sizeof_cmsghdr;
240
+ let aligned_cmsg_len = if self . next == 0 {
241
+ // CMSG_FIRSTHDR
242
+ cmsg_len
243
+ } else {
244
+ // CMSG_NXTHDR
245
+ cmsg_align ( cmsg_len)
246
+ } ;
235
247
236
248
// Advance our internal pointer.
237
- if cmsg_align ( cmsg_len ) > buf. len ( ) {
249
+ if aligned_cmsg_len > self . buf . len ( ) {
238
250
return None ;
239
251
}
240
- self . 0 = & buf[ cmsg_align ( cmsg_len) ..] ;
252
+ self . buf = & self . buf [ aligned_cmsg_len..] ;
253
+ self . next += 1 ;
241
254
242
255
match ( cmsg. cmsg_level , cmsg. cmsg_type ) {
243
256
( libc:: SOL_SOCKET , libc:: SCM_RIGHTS ) => unsafe {
@@ -370,9 +383,9 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
370
383
msg_name : name as * const c_void ,
371
384
msg_namelen : namelen,
372
385
msg_iov : iov. as_ptr ( ) ,
373
- msg_iovlen : iov. len ( ) as size_t ,
386
+ msg_iovlen : iov. len ( ) as type_of_msg_iovlen ,
374
387
msg_control : cmsg_ptr,
375
- msg_controllen : capacity as size_t ,
388
+ msg_controllen : capacity as type_of_cmsg_len ,
376
389
msg_flags : 0 ,
377
390
} ;
378
391
let ret = unsafe { ffi:: sendmsg ( fd, & mhdr, flags. bits ( ) ) } ;
@@ -393,9 +406,9 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
393
406
msg_name : & mut address as * const _ as * const c_void ,
394
407
msg_namelen : mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ,
395
408
msg_iov : iov. as_ptr ( ) as * const IoVec < & [ u8 ] > , // safe cast to add const-ness
396
- msg_iovlen : iov. len ( ) as size_t ,
409
+ msg_iovlen : iov. len ( ) as type_of_msg_iovlen ,
397
410
msg_control : msg_control as * const c_void ,
398
- msg_controllen : msg_controllen as size_t ,
411
+ msg_controllen : msg_controllen as type_of_cmsg_len ,
399
412
msg_flags : 0 ,
400
413
} ;
401
414
let ret = unsafe { ffi:: recvmsg ( fd, & mut mhdr, flags. bits ( ) ) } ;
0 commit comments