diff options
author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-06-27 19:17:32 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-27 19:17:32 +0900 |
commit | b6396caf3116000ca7a54a67bd339b108b166759 (patch) | |
tree | f0dd683cc0cc4ffb2ff9f5cb28023b221a53cb41 | |
parent | 5062033f8bd19354743a6d42fff108de351cc40a (diff) | |
parent | 40c46f4306742542871c7c438b6506baa42bbed4 (diff) | |
download | rust-libc-b6396caf3116000ca7a54a67bd339b108b166759.tar.gz |
Merge pull request #1792 from jasonbking/cmsg
-rw-r--r-- | libc-test/build.rs | 11 | ||||
-rw-r--r-- | libc-test/test/cmsg.rs | 1 | ||||
-rw-r--r-- | src/unix/solarish/mod.rs | 56 |
3 files changed, 65 insertions, 3 deletions
diff --git a/libc-test/build.rs b/libc-test/build.rs index 1d1f953080..1e602618ae 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 c95899cef5..38a8ce1508 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 c30e11593d..c60e678040 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; |