From 836c06d3dc1f57a894be1e68e8514367e42e0917 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Wed, 19 Jul 2017 07:41:22 +1000 Subject: [PATCH 1/5] Add OpenBSD compatibility to events --- src/sys/event.rs | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/sys/event.rs b/src/sys/event.rs index 95b7619eca..1ac9c5f176 100644 --- a/src/sys/event.rs +++ b/src/sys/event.rs @@ -18,17 +18,16 @@ pub struct KEvent { kevent: libc::kevent, } -#[cfg(any(target_os = "openbsd", target_os = "freebsd", - target_os = "dragonfly", target_os = "macos", - target_os = "ios"))] +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd"))] type type_of_udata = *mut libc::c_void; -#[cfg(any(target_os = "openbsd", target_os = "freebsd", - target_os = "dragonfly", target_os = "macos", - target_os = "ios"))] +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos"))] type type_of_data = libc::intptr_t; #[cfg(any(target_os = "netbsd"))] type type_of_udata = intptr_t; -#[cfg(any(target_os = "netbsd"))] +#[cfg(any(target_os = "netbsd", target_os = "openbsd"))] type type_of_data = libc::int64_t; #[cfg(not(target_os = "netbsd"))] @@ -78,10 +77,11 @@ pub enum EventFilter { EVFILT_TIMER = libc::EVFILT_TIMER, } -#[cfg(any(target_os = "macos", target_os = "ios", - target_os = "freebsd", target_os = "dragonfly"))] +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd"))] pub type type_of_event_flag = u16; -#[cfg(any(target_os = "netbsd", target_os = "openbsd"))] +#[cfg(any(target_os = "netbsd"))] pub type type_of_event_flag = u32; libc_bitflags!{ pub flags EventFlag: type_of_event_flag { @@ -89,6 +89,14 @@ libc_bitflags!{ EV_CLEAR, EV_DELETE, EV_DISABLE, + // No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT. + // These have been commited to the -current branch though and are + // expected to be part of the OpenBSD 6.2 release in Nov 2017. + // See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2 + // https://github.com/rust-lang/libc/pull/613 + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "netbsd"))] EV_DISPATCH, #[cfg(target_os = "freebsd")] EV_DROP, @@ -105,7 +113,9 @@ libc_bitflags!{ EV_OOBAND, #[cfg(any(target_os = "macos", target_os = "ios"))] EV_POLL, - #[cfg(not(target_os = "openbsd"))] + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "netbsd"))] EV_RECEIPT, EV_SYSFLAGS, } @@ -315,13 +325,13 @@ fn test_struct_kevent() { let expected = libc::kevent{ident: 0xdeadbeef, filter: libc::EVFILT_READ, - flags: libc::EV_DISPATCH | libc::EV_ADD, + flags: libc::EV_ONESHOT | libc::EV_ADD, fflags: libc::NOTE_CHILD | libc::NOTE_EXIT, data: 0x1337, udata: udata as type_of_udata}; let actual = KEvent::new(0xdeadbeef, EventFilter::EVFILT_READ, - EV_DISPATCH | EV_ADD, + EV_ONESHOT | EV_ADD, NOTE_CHILD | NOTE_EXIT, 0x1337, udata); From 0874cfa059b4a30168c52f470108ee7ca88ea273 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Wed, 19 Jul 2017 07:42:02 +1000 Subject: [PATCH 2/5] Add OpenBSD compatibility to signals --- src/sys/signal.rs | 193 +++++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 90 deletions(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index f885af9238..d7e9d91d84 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -3,13 +3,14 @@ use libc; use {Errno, Error, Result}; -use std::fmt; -use std::fmt::Debug; use std::mem; #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] use std::os::unix::io::RawFd; use std::ptr; +#[cfg(not(target_os = "openbsd"))] +pub use self::sigevent::*; + // Currently there is only one definition of c_int in libc, as well as only one // type for signal constants. // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately @@ -488,102 +489,114 @@ pub enum SigevNotify { si_value: libc::intptr_t }, } -/// Used to request asynchronous notification of the completion of certain -/// events, such as POSIX AIO and timers. -#[repr(C)] -pub struct SigEvent { - sigevent: libc::sigevent -} +#[cfg(not(target_os = "openbsd"))] +mod sigevent { + use libc; + use std::mem; + use std::ptr; + use std::fmt::{self, Debug}; + use super::SigevNotify; + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + use super::type_of_thread_id; + + /// Used to request asynchronous notification of the completion of certain + /// events, such as POSIX AIO and timers. + #[repr(C)] + pub struct SigEvent { + sigevent: libc::sigevent + } + + impl SigEvent { + /// **Note:** this constructor does not allow the user to set the + /// `sigev_notify_kevent_flags` field. That's considered ok because on FreeBSD + /// at least those flags don't do anything useful. That field is part of a + /// union that shares space with the more genuinely useful fields. + /// + /// **Note:** This constructor also doesn't allow the caller to set the + /// `sigev_notify_function` or `sigev_notify_attributes` fields, which are + /// required for `SIGEV_THREAD`. That's considered ok because on no operating + /// system is `SIGEV_THREAD` the most efficient way to deliver AIO + /// notification. FreeBSD and DragonFly BSD programs should prefer `SIGEV_KEVENT`. + /// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or + /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the + /// more genuinely useful `sigev_notify_thread_id` + pub fn new(sigev_notify: SigevNotify) -> SigEvent { + let mut sev = unsafe { mem::zeroed::()}; + sev.sigev_notify = match sigev_notify { + SigevNotify::SigevNone => libc::SIGEV_NONE, + SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT, + #[cfg(target_os = "freebsd")] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))] + SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined + }; + sev.sigev_signo = match sigev_notify { + SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{ kq, ..} => kq, + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int, + _ => 0 + }; + sev.sigev_value.sival_ptr = match sigev_notify { + SigevNotify::SigevNone => ptr::null_mut::(), + SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void, + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void, + }; + SigEvent::set_tid(&mut sev, &sigev_notify); + SigEvent{sigevent: sev} + } -impl SigEvent { - // Note: this constructor does not allow the user to set the - // sigev_notify_kevent_flags field. That's considered ok because on FreeBSD - // at least those flags don't do anything useful. That field is part of a - // union that shares space with the more genuinely useful - // Note: This constructor also doesn't allow the caller to set the - // sigev_notify_function or sigev_notify_attributes fields, which are - // required for SIGEV_THREAD. That's considered ok because on no operating - // system is SIGEV_THREAD the most efficient way to deliver AIO - // notification. FreeBSD and Dragonfly programs should prefer SIGEV_KEVENT. - // Linux, Solaris, and portable programs should prefer SIGEV_THREAD_ID or - // SIGEV_SIGNAL. That field is part of a union that shares space with the - // more genuinely useful sigev_notify_thread_id - pub fn new(sigev_notify: SigevNotify) -> SigEvent { - let mut sev = unsafe { mem::zeroed::()}; - sev.sigev_notify = match sigev_notify { - SigevNotify::SigevNone => libc::SIGEV_NONE, - SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL, - #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] - SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT, - #[cfg(target_os = "freebsd")] - SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, - #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))] - SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, - #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))] - SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined - }; - sev.sigev_signo = match sigev_notify { - SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int, - #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] - SigevNotify::SigevKevent{ kq, ..} => kq, - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int, - _ => 0 - }; - sev.sigev_value.sival_ptr = match sigev_notify { - SigevNotify::SigevNone => ptr::null_mut::(), - SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void, - #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] - SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void, - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void, - }; - SigEvent::set_tid(&mut sev, &sigev_notify); - SigEvent{sigevent: sev} - } + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) { + sev.sigev_notify_thread_id = match sigev_notify { + &SigevNotify::SigevThreadId { thread_id, .. } => thread_id, + _ => 0 as type_of_thread_id + }; + } - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) { - sev.sigev_notify_thread_id = match sigev_notify { - &SigevNotify::SigevThreadId { thread_id, .. } => thread_id, - _ => 0 as type_of_thread_id - }; - } + #[cfg(not(any(target_os = "freebsd", target_os = "linux")))] + fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) { + } - #[cfg(not(any(target_os = "freebsd", target_os = "linux")))] - fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) { + pub fn sigevent(&self) -> libc::sigevent { + self.sigevent + } } - pub fn sigevent(&self) -> libc::sigevent { - self.sigevent - } -} + impl Debug for SigEvent { + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("SigEvent") + .field("sigev_notify", &self.sigevent.sigev_notify) + .field("sigev_signo", &self.sigevent.sigev_signo) + .field("sigev_value", &self.sigevent.sigev_value.sival_ptr) + .field("sigev_notify_thread_id", + &self.sigevent.sigev_notify_thread_id) + .finish() + } -impl Debug for SigEvent { - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("SigEvent") - .field("sigev_notify", &self.sigevent.sigev_notify) - .field("sigev_signo", &self.sigevent.sigev_signo) - .field("sigev_value", &self.sigevent.sigev_value.sival_ptr) - .field("sigev_notify_thread_id", - &self.sigevent.sigev_notify_thread_id) - .finish() - } - - #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("SigEvent") - .field("sigev_notify", &self.sigevent.sigev_notify) - .field("sigev_signo", &self.sigevent.sigev_signo) - .field("sigev_value", &self.sigevent.sigev_value.sival_ptr) - .finish() + #[cfg(not(any(target_os = "freebsd", target_os = "linux")))] + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("SigEvent") + .field("sigev_notify", &self.sigevent.sigev_notify) + .field("sigev_signo", &self.sigevent.sigev_signo) + .field("sigev_value", &self.sigevent.sigev_value.sival_ptr) + .finish() + } } -} -impl<'a> From<&'a libc::sigevent> for SigEvent { - fn from(sigevent: &libc::sigevent) -> Self { - SigEvent{ sigevent: sigevent.clone() } + impl<'a> From<&'a libc::sigevent> for SigEvent { + fn from(sigevent: &libc::sigevent) -> Self { + SigEvent{ sigevent: sigevent.clone() } + } } } From 000366ca6657691c3c09a2333d4d982e2ce6d53d Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Wed, 19 Jul 2017 02:43:10 +1000 Subject: [PATCH 3/5] Fix tests on OpenBSD There appears to be some interaction with test_pathconf_limited and another one when they are run in parallel, causing it to return ENOENT so the path has been changed from . to /. --- nix-test/src/const.c | 25 +++++++++++++++++++++++++ src/sys/event.rs | 2 +- test/test_unistd.rs | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/nix-test/src/const.c b/nix-test/src/const.c index b0376d48e6..bb70fc9239 100644 --- a/nix-test/src/const.c +++ b/nix-test/src/const.c @@ -209,6 +209,31 @@ get_int_const(const char* err) { GET_CONST(ECANCELED); #endif +#if defined(__OpenBSD__) + GET_CONST(EAUTH); + GET_CONST(EBADRPC); + GET_CONST(ECANCELED); + GET_CONST(EDQUOT); + GET_CONST(EFTYPE); + GET_CONST(EILSEQ); + GET_CONST(EIPSEC); + GET_CONST(EMEDIUMTYPE); + GET_CONST(ENEEDAUTH); + GET_CONST(ENOATTR); + GET_CONST(ENOMEDIUM); + GET_CONST(ENOTSUP); + GET_CONST(EOPNOTSUPP); + GET_CONST(EOVERFLOW); + GET_CONST(EPROCLIM); + GET_CONST(EPROCUNAVAIL); + GET_CONST(EPROGMISMATCH); + GET_CONST(EPROGUNAVAIL); + GET_CONST(EREMOTE); + GET_CONST(ERPCMISMATCH); + GET_CONST(ESTALE); + GET_CONST(EUSERS); +#endif + #ifdef DARWIN GET_CONST(EPWROFF); GET_CONST(EDEVERR); diff --git a/src/sys/event.rs b/src/sys/event.rs index 1ac9c5f176..9215c65431 100644 --- a/src/sys/event.rs +++ b/src/sys/event.rs @@ -339,7 +339,7 @@ fn test_struct_kevent() { assert!(expected.filter == actual.filter() as type_of_event_filter); assert!(expected.flags == actual.flags().bits()); assert!(expected.fflags == actual.fflags().bits()); - assert!(expected.data == actual.data()); + assert!(expected.data == actual.data() as type_of_data); assert!(expected.udata == actual.udata() as type_of_udata); assert!(mem::size_of::() == mem::size_of::()); } diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 944232caaf..09143c586d 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -244,7 +244,7 @@ fn test_fpathconf_limited() { #[test] fn test_pathconf_limited() { // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test - let path_max = pathconf(".", PathconfVar::PATH_MAX); + let path_max = pathconf("/", PathconfVar::PATH_MAX); assert!(path_max.expect("pathconf failed").expect("PATH_MAX is unlimited") > 0); } From 6ea77da65132e782167705fc2f6963fc82728460 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Sun, 23 Jul 2017 19:54:43 +1000 Subject: [PATCH 4/5] Correct access of cmsg ancillary data on first header Also updates cmsg types to match structs on non-Linux OSes. The implementation of CmsgInterator did not correctly mirror the way the CMSG_FIRSTHDR and CMSG_NEXTHDR macros work in C. CMSG_FIRSTHDR does not attempt to align access since the pointer is already aligned due to being part of the msghdr struct. CmsgInterator was always aligning access which happened to work on all platforms except OpenBSD where the use of alignment was adding unexpected bytes to the expected size and causing the `cmsg_align(cmsg_len) > self.buf.len()` guard clause to return early. --- src/sys/socket/ffi.rs | 19 +++++++++++++++---- src/sys/socket/mod.rs | 37 +++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/sys/socket/ffi.rs b/src/sys/socket/ffi.rs index 55a47eb642..265a97c976 100644 --- a/src/sys/socket/ffi.rs +++ b/src/sys/socket/ffi.rs @@ -3,9 +3,12 @@ pub use libc::{socket, listen, bind, accept, connect, setsockopt, sendto, recvfrom, getsockname, getpeername, recv, send}; -use libc::{c_int, c_void, socklen_t, size_t, ssize_t}; +use libc::{c_int, c_void, socklen_t, ssize_t}; -#[cfg(target_os = "macos")] +#[cfg(not(target_os = "macos"))] +use libc::size_t; + +#[cfg(not(target_os = "linux"))] use libc::c_uint; use sys::uio::IoVec; @@ -23,19 +26,27 @@ pub type type_of_cmsg_data = c_uint; #[cfg(not(target_os = "macos"))] pub type type_of_cmsg_data = size_t; +#[cfg(target_os = "linux")] +pub type type_of_msg_iovlen = size_t; + +#[cfg(not(target_os = "linux"))] +pub type type_of_msg_iovlen = c_uint; + // Private because we don't expose any external functions that operate // directly on this type; we just use it internally at FFI boundaries. // Note that in some cases we store pointers in *const fields that the // kernel will proceed to mutate, so users should be careful about the // actual mutability of data pointed to by this structure. +// +// FIXME: Replace these structs with the ones defined in libc #[repr(C)] pub struct msghdr<'a> { pub msg_name: *const c_void, pub msg_namelen: socklen_t, pub msg_iov: *const IoVec<&'a [u8]>, - pub msg_iovlen: size_t, + pub msg_iovlen: type_of_msg_iovlen, pub msg_control: *const c_void, - pub msg_controllen: size_t, + pub msg_controllen: type_of_cmsg_len, pub msg_flags: c_int, } diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 86129fcf00..6ab1684ad0 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -168,7 +168,7 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) { } -use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data}; +use self::ffi::{cmsghdr, msghdr, type_of_cmsg_data, type_of_msg_iovlen, type_of_cmsg_len}; /// A structure used to make room in a cmsghdr passed to recvmsg. The /// size and alignment match that of a cmsghdr followed by a T, but the @@ -204,11 +204,17 @@ impl<'a> RecvMsg<'a> { /// Iterate over the valid control messages pointed to by this /// msghdr. pub fn cmsgs(&self) -> CmsgIterator { - CmsgIterator(self.cmsg_buffer) + CmsgIterator { + buf: self.cmsg_buffer, + next: 0 + } } } -pub struct CmsgIterator<'a>(&'a [u8]); +pub struct CmsgIterator<'a> { + buf: &'a [u8], + next: usize, +} impl<'a> Iterator for CmsgIterator<'a> { type Item = ControlMessage<'a>; @@ -217,12 +223,11 @@ impl<'a> Iterator for CmsgIterator<'a> { // although we handle the invariants in slightly different places to // get a better iterator interface. fn next(&mut self) -> Option> { - let buf = self.0; let sizeof_cmsghdr = mem::size_of::(); - if buf.len() < sizeof_cmsghdr { + if self.buf.len() < sizeof_cmsghdr { return None; } - let cmsg: &cmsghdr = unsafe { mem::transmute(buf.as_ptr()) }; + let cmsg: &cmsghdr = unsafe { mem::transmute(self.buf.as_ptr()) }; // This check is only in the glibc implementation of CMSG_NXTHDR // (although it claims the kernel header checks this), but such @@ -232,12 +237,20 @@ impl<'a> Iterator for CmsgIterator<'a> { return None; } let len = cmsg_len - sizeof_cmsghdr; + let aligned_cmsg_len = if self.next == 0 { + // CMSG_FIRSTHDR + cmsg_len + } else { + // CMSG_NXTHDR + cmsg_align(cmsg_len) + }; // Advance our internal pointer. - if cmsg_align(cmsg_len) > buf.len() { + if aligned_cmsg_len > self.buf.len() { return None; } - self.0 = &buf[cmsg_align(cmsg_len)..]; + self.buf = &self.buf[aligned_cmsg_len..]; + self.next += 1; match (cmsg.cmsg_level, cmsg.cmsg_type) { (libc::SOL_SOCKET, libc::SCM_RIGHTS) => unsafe { @@ -370,9 +383,9 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<' msg_name: name as *const c_void, msg_namelen: namelen, msg_iov: iov.as_ptr(), - msg_iovlen: iov.len() as size_t, + msg_iovlen: iov.len() as type_of_msg_iovlen, msg_control: cmsg_ptr, - msg_controllen: capacity as size_t, + msg_controllen: capacity as type_of_cmsg_len, msg_flags: 0, }; 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<& msg_name: &mut address as *const _ as *const c_void, msg_namelen: mem::size_of::() as socklen_t, msg_iov: iov.as_ptr() as *const IoVec<&[u8]>, // safe cast to add const-ness - msg_iovlen: iov.len() as size_t, + msg_iovlen: iov.len() as type_of_msg_iovlen, msg_control: msg_control as *const c_void, - msg_controllen: msg_controllen as size_t, + msg_controllen: msg_controllen as type_of_cmsg_len, msg_flags: 0, }; let ret = unsafe { ffi::recvmsg(fd, &mut mhdr, flags.bits()) }; From 0fbd22362e5e08f73154fc6a87af221e8f0a9075 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Tue, 8 Aug 2017 07:03:36 +1000 Subject: [PATCH 5/5] Add entry to CHANGELOG about OpenBSD fixes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d278d677..8c66fa230a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). It accepts a `None` value for default protocol that was specified with zero using `c_int`. ([#647](https://github.com/nix-rust/nix/pull/647)) +# Fixed +- Fix compilation and tests for OpenBSD targets + ([#688](https://github.com/nix-rust/nix/pull/688)) + ## [0.9.0] 2017-07-23 ### Added