diff --git a/libc-test/Cargo.toml b/libc-test/Cargo.toml index 8d2d9033..0b6866d4 100644 --- a/libc-test/Cargo.toml +++ b/libc-test/Cargo.toml @@ -52,3 +52,8 @@ harness = false name = "cmsg" path = "test/cmsg.rs" harness = true + +[[test]] +name = "errqueue" +path = "test/errqueue.rs" +harness = true diff --git a/libc-test/build.rs b/libc-test/build.rs index b5659329..8fd2e7c3 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -10,6 +10,9 @@ fn do_cc() { if cfg!(unix) && !target.contains("wasi") { cc::Build::new().file("src/cmsg.c").compile("cmsg"); } + if target.contains("android") || target.contains("linux") { + cc::Build::new().file("src/errqueue.c").compile("errqueue"); + } } fn do_ctest() { diff --git a/libc-test/src/errqueue.c b/libc-test/src/errqueue.c new file mode 100644 index 00000000..931ca91b --- /dev/null +++ b/libc-test/src/errqueue.c @@ -0,0 +1,10 @@ +#include +#include + +// SO_EE_OFFENDER is defined as a macro in linux/errqueue.h. This file wraps +// that macro in a function so we can test the reimplementation in this package +// is equivalent. + +struct sockaddr *so_ee_offender(struct sock_extended_err *ee) { + return SO_EE_OFFENDER(ee); +} diff --git a/libc-test/test/errqueue.rs b/libc-test/test/errqueue.rs new file mode 100644 index 00000000..8d0c7bb7 --- /dev/null +++ b/libc-test/test/errqueue.rs @@ -0,0 +1,22 @@ +//! Compare libc's SO_EE_OFFENDER function against the actual C macro + +extern crate libc; + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod t { + use libc::{self, sock_extended_err, sockaddr}; + + extern "C" { + pub fn so_ee_offender(ee: *const sock_extended_err) -> *mut sockaddr; + } + + #[test] + fn test_cmsg_data() { + for l in 0..128 { + let ee = l as *const sock_extended_err; + unsafe { + assert_eq!(libc::SO_EE_OFFENDER(ee), so_ee_offender(ee)); + } + } + } +}