Skip to content

Commit a39e409

Browse files
committed
1 parent 64815c6 commit a39e409

File tree

5 files changed

+42
-21
lines changed

5 files changed

+42
-21
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6262
only available on x86, x86-64, and ARM, and also not on Android.
6363
- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
6464
([#623](https://github.com/nix-rust/nix/pull/623))
65+
- Fixed field types of `sys::socket::ffi::{msghdr, cmsghdr}` on
66+
non-Linux platforms. ([#](https://...))
6567

6668
## [0.8.1] 2017-04-16
6769

nix-test/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub fn assert_size_of<T>(name: &str) {
3636
assert!(expect > 0, "undefined type {}", name);
3737

3838
if mem::size_of::<T>() != expect {
39-
panic!("incorrectly sized type; expect={}; actual={}",
40-
expect, mem::size_of::<T>());
39+
panic!("incorrectly sized type; type={} expect={}; actual={}",
40+
name, expect, mem::size_of::<T>());
4141
}
4242
}
4343
}

nix-test/src/sizes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ size_of(const char* type) {
2424

2525
// sys/socket
2626
SIZE_OF_S(sockaddr_storage);
27+
SIZE_OF_S(msghdr);
28+
SIZE_OF_S(cmsghdr);
2729

2830
// sys/uio
2931
SIZE_OF_S(iovec);

src/sys/socket/ffi.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
pub use libc::{socket, listen, bind, accept, connect, setsockopt, sendto, recvfrom, getsockname, getpeername, recv, send};
55

6-
use libc::{c_int, c_void, socklen_t, size_t, ssize_t};
6+
use libc::{c_int, c_void, socklen_t, ssize_t};
7+
8+
#[cfg(not(target_os = "macos"))]
9+
use libc::size_t;
710

811
#[cfg(target_os = "macos")]
912
use libc::c_uint;
@@ -18,10 +21,22 @@ pub type type_of_cmsg_len = socklen_t;
1821

1922
// OSX always aligns struct cmsghdr as if it were a 32-bit OS
2023
#[cfg(target_os = "macos")]
21-
pub type type_of_cmsg_data = c_uint;
24+
pub type align_of_cmsg_data = c_uint;
2225

2326
#[cfg(not(target_os = "macos"))]
24-
pub type type_of_cmsg_data = size_t;
27+
pub type align_of_cmsg_data = size_t;
28+
29+
#[cfg(target_os = "linux")]
30+
pub type type_of_msgiov_len = size_t;
31+
32+
#[cfg(not(target_os = "linux"))]
33+
pub type type_of_msgiov_len = c_int;
34+
35+
#[cfg(target_os = "linux")]
36+
pub type type_of_msg_controllen = size_t;
37+
38+
#[cfg(not(target_os = "linux"))]
39+
pub type type_of_msg_controllen = socklen_t;
2540

2641
// Private because we don't expose any external functions that operate
2742
// directly on this type; we just use it internally at FFI boundaries.
@@ -33,9 +48,9 @@ pub struct msghdr<'a> {
3348
pub msg_name: *const c_void,
3449
pub msg_namelen: socklen_t,
3550
pub msg_iov: *const IoVec<&'a [u8]>,
36-
pub msg_iovlen: size_t,
51+
pub msg_iovlen: type_of_msgiov_len,
3752
pub msg_control: *const c_void,
38-
pub msg_controllen: size_t,
53+
pub msg_controllen: type_of_msg_controllen,
3954
pub msg_flags: c_int,
4055
}
4156

@@ -47,7 +62,6 @@ pub struct cmsghdr {
4762
pub cmsg_len: type_of_cmsg_len,
4863
pub cmsg_level: c_int,
4964
pub cmsg_type: c_int,
50-
pub cmsg_data: [type_of_cmsg_data; 0]
5165
}
5266

5367
extern {

src/sys/socket/mod.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) {
8585
}
8686

8787

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};
8990

9091
/// A structure used to make room in a cmsghdr passed to recvmsg. The
9192
/// size and alignment match that of a cmsghdr followed by a T, but the
@@ -156,17 +157,18 @@ impl<'a> Iterator for CmsgIterator<'a> {
156157
}
157158
self.0 = &buf[cmsg_align(cmsg_len)..];
158159

160+
let cmsg_data = &buf[cmsg_align(sizeof_cmsghdr)..];
159161
match (cmsg.cmsg_level, cmsg.cmsg_type) {
160162
(SOL_SOCKET, SCM_RIGHTS) => unsafe {
161163
Some(ControlMessage::ScmRights(
162164
slice::from_raw_parts(
163-
&cmsg.cmsg_data as *const _ as *const _, 1)))
165+
cmsg_data.as_ptr() as *const _, 1)))
164166
},
165167
(_, _) => unsafe {
166168
Some(ControlMessage::Unknown(UnknownCmsg(
167169
&cmsg,
168170
slice::from_raw_parts(
169-
&cmsg.cmsg_data as *const _ as *const _,
171+
cmsg_data.as_ptr() as *const _,
170172
len))))
171173
}
172174
}
@@ -191,7 +193,7 @@ pub enum ControlMessage<'a> {
191193
pub struct UnknownCmsg<'a>(&'a cmsghdr, &'a [u8]);
192194

193195
fn cmsg_align(len: usize) -> usize {
194-
let align_bytes = mem::size_of::<type_of_cmsg_data>() - 1;
196+
let align_bytes = mem::size_of::<align_of_cmsg_data>() - 1;
195197
(len + align_bytes) & !align_bytes
196198
}
197199

@@ -213,8 +215,8 @@ impl<'a> ControlMessage<'a> {
213215
}
214216
}
215217

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
218+
// Unsafe: start and end of buffer must be cmsg_align'd.
219+
// Updates the provided slice; panics if the buffer
218220
// is too small.
219221
unsafe fn encode_into<'b>(&self, buf: &mut &'b mut [u8]) {
220222
match *self {
@@ -223,7 +225,6 @@ impl<'a> ControlMessage<'a> {
223225
cmsg_len: self.len() as type_of_cmsg_len,
224226
cmsg_level: SOL_SOCKET,
225227
cmsg_type: SCM_RIGHTS,
226-
cmsg_data: [],
227228
};
228229
copy_bytes(&cmsg, buf);
229230

@@ -287,9 +288,9 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
287288
msg_name: name as *const c_void,
288289
msg_namelen: namelen,
289290
msg_iov: iov.as_ptr(),
290-
msg_iovlen: iov.len() as size_t,
291+
msg_iovlen: iov.len() as type_of_msgiov_len,
291292
msg_control: cmsg_ptr,
292-
msg_controllen: capacity as size_t,
293+
msg_controllen: capacity as type_of_msg_controllen,
293294
msg_flags: 0,
294295
};
295296
let ret = unsafe { ffi::sendmsg(fd, &mhdr, flags.bits()) };
@@ -310,9 +311,9 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
310311
msg_name: &mut address as *const _ as *const c_void,
311312
msg_namelen: mem::size_of::<sockaddr_storage>() as socklen_t,
312313
msg_iov: iov.as_ptr() as *const IoVec<&[u8]>, // safe cast to add const-ness
313-
msg_iovlen: iov.len() as size_t,
314+
msg_iovlen: iov.len() as type_of_msgiov_len,
314315
msg_control: msg_control as *const c_void,
315-
msg_controllen: msg_controllen as size_t,
316+
msg_controllen: msg_controllen as type_of_msg_controllen,
316317
msg_flags: 0,
317318
};
318319
let ret = unsafe { ffi::recvmsg(fd, &mut mhdr, flags.bits()) };
@@ -692,6 +693,8 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
692693

693694
#[test]
694695
pub fn test_struct_sizes() {
695-
use nixtest;
696-
nixtest::assert_size_of::<sockaddr_storage>("sockaddr_storage");
696+
use nixtest::assert_size_of;
697+
assert_size_of::<sockaddr_storage>("sockaddr_storage");
698+
assert_size_of::<msghdr>("msghdr");
699+
assert_size_of::<cmsghdr>("cmsghdr");
697700
}

0 commit comments

Comments
 (0)