diff --git a/libc-test/build.rs b/libc-test/build.rs index 1d1f953080bb1c1a595d1bd129ef6d813c034d88..1e602618ae7204e434abf30a02ef078e90786e5f 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -8,9 +8,16 @@ use std::env; fn do_cc() { let target = env::var("TARGET").unwrap(); if cfg!(unix) { - let exclude = ["wasi", "solaris", "illumos"]; + let exclude = ["wasi"]; if !exclude.iter().any(|x| target.contains(x)) { - cc::Build::new().file("src/cmsg.c").compile("cmsg"); + let mut cmsg = cc::Build::new(); + + cmsg.file("src/cmsg.c"); + + if target.contains("solaris") || target.contains("illumos") { + cmsg.define("_XOPEN_SOURCE", "700"); + } + cmsg.compile("cmsg"); } } if target.contains("android") || target.contains("linux") { diff --git a/libc-test/test/cmsg.rs b/libc-test/test/cmsg.rs index c95899cef516c48e73fa88f57f39cc15b1a3ab35..38a8ce15089011dd7748af93dc9bc56f64632f43 100644 --- a/libc-test/test/cmsg.rs +++ b/libc-test/test/cmsg.rs @@ -4,7 +4,6 @@ extern crate libc; #[cfg(unix)] -#[cfg(not(any(target_os = "solaris", target_os = "illumos")))] mod t { use libc::{self, c_uchar, c_uint, c_void, cmsghdr, msghdr}; diff --git a/src/unix/solarish/mod.rs b/src/unix/solarish/mod.rs index c30e11593d69498ac9d0ea02f1b688f80de7247f..c60e678040037e3981a8788b815b6bbbd7a60273 100644 --- a/src/unix/solarish/mod.rs +++ b/src/unix/solarish/mod.rs @@ -1998,7 +1998,63 @@ pub const PRIO_PROCESS: ::c_int = 0; pub const PRIO_PGRP: ::c_int = 1; pub const PRIO_USER: ::c_int = 2; +// As per sys/socket.h, header alignment must be 8 bytes on SPARC +// and 4 bytes everywhere else: +#[cfg(target_arch = "sparc64")] +const _CMSG_HDR_ALIGNMENT: usize = 8; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +const _CMSG_HDR_ALIGNMENT: usize = 4; + +const _CMSG_DATA_ALIGNMENT: usize = ::mem::size_of::<::c_int>(); + +fn _CMSG_HDR_ALIGN(p: usize) -> usize { + (p + _CMSG_HDR_ALIGNMENT - 1) & !(_CMSG_HDR_ALIGNMENT - 1) +} + +fn _CMSG_DATA_ALIGN(p: usize) -> usize { + (p + _CMSG_DATA_ALIGNMENT - 1) & !(_CMSG_DATA_ALIGNMENT - 1) +} + f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + _CMSG_DATA_ALIGN(cmsg.offset(1) as usize) as *mut ::c_uchar + } + + pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _CMSG_DATA_ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { + if ((*mhdr).msg_controllen as usize) < ::mem::size_of::<::cmsghdr>() { + 0 as *mut ::cmsghdr + } else { + (*mhdr).msg_control as *mut ::cmsghdr + } + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize + + ::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize) + as *mut ::cmsghdr + } + } + + pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + _CMSG_HDR_ALIGN(::mem::size_of::<::cmsghdr>() as usize + + length as usize) as ::c_uint + } + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize;