From 06938add2d1cf8bf5cf8ae932fd9209054c1d69b Mon Sep 17 00:00:00 2001
From: Matthew McPherrin <git@mcpherrin.ca>
Date: Mon, 2 Dec 2019 12:37:25 -0800
Subject: [PATCH] Add test for SO_EE_OFFENDER

Modelled after the cmsg tests, this wraps the C macro into a function, and then
compares the results to the Rust implementation in libc.
---
 libc-test/Cargo.toml       |  5 +++++
 libc-test/build.rs         |  3 +++
 libc-test/src/errqueue.c   | 10 ++++++++++
 libc-test/test/errqueue.rs | 22 ++++++++++++++++++++++
 4 files changed, 40 insertions(+)
 create mode 100644 libc-test/src/errqueue.c
 create mode 100644 libc-test/test/errqueue.rs

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 <time.h>
+#include <linux/errqueue.h>
+
+// 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));
+            }
+        }
+    }
+}
-- 
GitLab