Skip to content

Commit 1ae7f8e

Browse files
committed
Auto merge of #397 - fiveop:asomers_master, r=@posborne
Fix nix on FreeBSD (rebased on master)
2 parents 437c8f2 + 077d979 commit 1ae7f8e

File tree

4 files changed

+60
-44
lines changed

4 files changed

+60
-44
lines changed

src/sys/socket/ffi.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@
44
pub use libc::{socket, listen, bind, accept, connect, setsockopt, sendto, recvfrom, getsockname, getpeername, recv, send};
55

66
use libc::{c_int, c_void, socklen_t, size_t, ssize_t};
7-
use sys::uio::IoVec;
87

8+
#[cfg(target_os = "macos")]
9+
use libc::c_uint;
10+
11+
use sys::uio::IoVec;
912

1013
#[cfg(target_os = "linux")]
1114
pub type type_of_cmsg_len = size_t;
1215

1316
#[cfg(not(target_os = "linux"))]
1417
pub type type_of_cmsg_len = socklen_t;
1518

19+
// OSX always aligns struct cmsghdr as if it were a 32-bit OS
20+
#[cfg(target_os = "macos")]
21+
pub type type_of_cmsg_data = c_uint;
22+
23+
#[cfg(not(target_os = "macos"))]
24+
pub type type_of_cmsg_data = size_t;
25+
1626
// Private because we don't expose any external functions that operate
1727
// directly on this type; we just use it internally at FFI boundaries.
1828
// Note that in some cases we store pointers in *const fields that the
@@ -37,7 +47,7 @@ pub struct cmsghdr {
3747
pub cmsg_len: type_of_cmsg_len,
3848
pub cmsg_level: c_int,
3949
pub cmsg_type: c_int,
40-
pub cmsg_data: [type_of_cmsg_len; 0]
50+
pub cmsg_data: [type_of_cmsg_data; 0]
4151
}
4252

4353
extern {

src/sys/socket/mod.rs

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

9696

97-
use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len};
97+
use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data};
9898

9999
/// A structure used to make room in a cmsghdr passed to recvmsg. The
100100
/// size and alignment match that of a cmsghdr followed by a T, but the
@@ -169,8 +169,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
169169
(SOL_SOCKET, SCM_RIGHTS) => unsafe {
170170
Some(ControlMessage::ScmRights(
171171
slice::from_raw_parts(
172-
&cmsg.cmsg_data as *const _ as *const _,
173-
len / mem::size_of::<RawFd>())))
172+
&cmsg.cmsg_data as *const _ as *const _, 1)))
174173
},
175174
(_, _) => unsafe {
176175
Some(ControlMessage::Unknown(UnknownCmsg(
@@ -201,12 +200,8 @@ pub enum ControlMessage<'a> {
201200
pub struct UnknownCmsg<'a>(&'a cmsghdr, &'a [u8]);
202201

203202
fn cmsg_align(len: usize) -> usize {
204-
let round_to = mem::size_of::<type_of_cmsg_len>();
205-
if len % round_to == 0 {
206-
len
207-
} else {
208-
len + round_to - (len % round_to)
209-
}
203+
let align_bytes = mem::size_of::<type_of_cmsg_data>() - 1;
204+
(len + align_bytes) & !align_bytes
210205
}
211206

212207
impl<'a> ControlMessage<'a> {
@@ -217,7 +212,7 @@ impl<'a> ControlMessage<'a> {
217212

218213
/// The value of CMSG_LEN on this message.
219214
fn len(&self) -> usize {
220-
mem::size_of::<cmsghdr>() + match *self {
215+
cmsg_align(mem::size_of::<cmsghdr>()) + match *self {
221216
ControlMessage::ScmRights(fds) => {
222217
mem::size_of_val(fds)
223218
},
@@ -240,7 +235,11 @@ impl<'a> ControlMessage<'a> {
240235
cmsg_data: [],
241236
};
242237
copy_bytes(&cmsg, buf);
243-
copy_bytes(fds, buf);
238+
239+
let padlen = cmsg_align(mem::size_of_val(&cmsg)) -
240+
mem::size_of_val(&cmsg);
241+
let buf2 = &mut &mut buf[padlen..];
242+
copy_bytes(fds, buf2);
244243
},
245244
ControlMessage::Unknown(UnknownCmsg(orig_cmsg, bytes)) => {
246245
copy_bytes(orig_cmsg, buf);
@@ -267,10 +266,10 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
267266
// multiple of size_t. Note also that the resulting vector claims
268267
// to have length == capacity, so it's presently uninitialized.
269268
let mut cmsg_buffer = unsafe {
270-
let mut vec = Vec::<size_t>::with_capacity(capacity / mem::size_of::<size_t>());
269+
let mut vec = Vec::<u8>::with_capacity(len);
271270
let ptr = vec.as_mut_ptr();
272271
mem::forget(vec);
273-
Vec::<u8>::from_raw_parts(ptr as *mut _, capacity, capacity)
272+
Vec::<u8>::from_raw_parts(ptr as *mut _, len, len)
274273
};
275274
{
276275
let mut ptr = &mut cmsg_buffer[..];
@@ -290,7 +289,7 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
290289
msg_iov: iov.as_ptr(),
291290
msg_iovlen: iov.len() as size_t,
292291
msg_control: cmsg_buffer.as_ptr() as *const c_void,
293-
msg_controllen: len as size_t,
292+
msg_controllen: capacity as size_t,
294293
msg_flags: 0,
295294
};
296295
let ret = unsafe { ffi::sendmsg(fd, &mhdr, flags.bits()) };

src/sys/socket/sockopt.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ macro_rules! getsockopt_impl {
4949

5050
// Helper to generate the sockopt accessors
5151
macro_rules! sockopt_impl {
52-
(GetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
53-
sockopt_impl!(GetOnly, $name, $level, $flag, $ty, GetStruct<$ty>);
54-
};
55-
5652
(GetOnly, $name:ident, $level:path, $flag:path, bool) => {
5753
sockopt_impl!(GetOnly, $name, $level, $flag, bool, GetBool);
5854
};
@@ -65,17 +61,6 @@ macro_rules! sockopt_impl {
6561
sockopt_impl!(GetOnly, $name, $level, $flag, usize, GetUsize);
6662
};
6763

68-
(GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
69-
#[derive(Copy, Clone, Debug)]
70-
pub struct $name;
71-
72-
getsockopt_impl!($name, $level, $flag, $ty, $getter);
73-
};
74-
75-
(SetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
76-
sockopt_impl!(SetOnly, $name, $level, $flag, $ty, SetStruct<$ty>);
77-
};
78-
7964
(SetOnly, $name:ident, $level:path, $flag:path, bool) => {
8065
sockopt_impl!(SetOnly, $name, $level, $flag, bool, SetBool);
8166
};
@@ -88,31 +73,50 @@ macro_rules! sockopt_impl {
8873
sockopt_impl!(SetOnly, $name, $level, $flag, usize, SetUsize);
8974
};
9075

91-
(SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
92-
#[derive(Copy, Clone, Debug)]
93-
pub struct $name;
76+
(Both, $name:ident, $level:path, $flag:path, bool) => {
77+
sockopt_impl!(Both, $name, $level, $flag, bool, GetBool, SetBool);
78+
};
9479

95-
setsockopt_impl!($name, $level, $flag, $ty, $setter);
80+
(Both, $name:ident, $level:path, $flag:path, u8) => {
81+
sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8);
9682
};
9783

98-
(Both, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty, $setter:ty) => {
84+
(Both, $name:ident, $level:path, $flag:path, usize) => {
85+
sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize);
86+
};
87+
88+
/*
89+
* Matchers with generic getter types must be placed at the end, so
90+
* they'll only match _after_ specialized matchers fail
91+
*/
92+
(GetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
93+
sockopt_impl!(GetOnly, $name, $level, $flag, $ty, GetStruct<$ty>);
94+
};
95+
96+
(GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
9997
#[derive(Copy, Clone, Debug)]
10098
pub struct $name;
10199

102-
setsockopt_impl!($name, $level, $flag, $ty, $setter);
103100
getsockopt_impl!($name, $level, $flag, $ty, $getter);
104101
};
105102

106-
(Both, $name:ident, $level:path, $flag:path, bool) => {
107-
sockopt_impl!(Both, $name, $level, $flag, bool, GetBool, SetBool);
103+
(SetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
104+
sockopt_impl!(SetOnly, $name, $level, $flag, $ty, SetStruct<$ty>);
108105
};
109106

110-
(Both, $name:ident, $level:path, $flag:path, u8) => {
111-
sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8);
107+
(SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
108+
#[derive(Copy, Clone, Debug)]
109+
pub struct $name;
110+
111+
setsockopt_impl!($name, $level, $flag, $ty, $setter);
112112
};
113113

114-
(Both, $name:ident, $level:path, $flag:path, usize) => {
115-
sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize);
114+
(Both, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty, $setter:ty) => {
115+
#[derive(Copy, Clone, Debug)]
116+
pub struct $name;
117+
118+
setsockopt_impl!($name, $level, $flag, $ty, $setter);
119+
getsockopt_impl!($name, $level, $flag, $ty, $getter);
116120
};
117121

118122
(Both, $name:ident, $level:path, $flag:path, $ty:ty) => {

src/unistd.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
176176
pub fn sethostname(name: &[u8]) -> Result<()> {
177177
// Handle some differences in type of the len arg across platforms.
178178
cfg_if! {
179-
if #[cfg(any(target_os = "macos", target_os = "ios"))] {
179+
if #[cfg(any(target_os = "dragonfly",
180+
target_os = "freebsd",
181+
target_os = "ios",
182+
target_os = "macos", ))] {
180183
type sethostname_len_t = c_int;
181184
} else {
182185
type sethostname_len_t = size_t;

0 commit comments

Comments
 (0)