From 59749267fa458952b33d259f51e7f195b6434fc1 Mon Sep 17 00:00:00 2001
From: Amanda Tait <atait@google.com>
Date: Mon, 27 Jul 2020 10:46:05 -0400
Subject: [PATCH] Add CMSG_* "macro" support to Fuchsia

This change defines and implements functions for the Fuchsia platform
corresponding to the C library CMSG_* macros, used for processing socket
control messages sent or received using the recv_msg(2)/send_msg(2)
syscalls.
---
 src/fuchsia/mod.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/src/fuchsia/mod.rs b/src/fuchsia/mod.rs
index 47170894..ecaf16c2 100644
--- a/src/fuchsia/mod.rs
+++ b/src/fuchsia/mod.rs
@@ -3250,6 +3250,60 @@ f! {
         dev |= (minor & 0xffffff00) << 12;
         dev
     }
+
+    pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar {
+        cmsg.offset(1) as *mut c_uchar
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) ->
+        *mut cmsghdr {
+        if ((*cmsg).cmsg_len as ::size_t) < ::mem::size_of::<cmsghdr>() {
+            core::ptr::null_mut()
+        } else if __CMSG_NEXT(cmsg).add(::mem::size_of::<cmsghdr>())
+            >= __MHDR_END(mhdr) {
+            core::ptr::null_mut()
+        } else {
+            __CMSG_NEXT(cmsg).cast()
+        }
+    }
+
+    pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
+        if (*mhdr).msg_controllen as ::size_t >= ::mem::size_of::<cmsghdr>() {
+            (*mhdr).msg_control.cast()
+        } else {
+            core::ptr::null_mut()
+        }
+    }
+
+    pub fn CMSG_ALIGN(len: ::size_t) -> ::size_t {
+        (len + ::mem::size_of::<::size_t>() - 1)
+            & !(::mem::size_of::<::size_t>() - 1)
+    }
+
+    pub fn CMSG_SPACE(len: ::c_uint) -> ::c_uint {
+        (CMSG_ALIGN(len as ::size_t) + CMSG_ALIGN(::mem::size_of::<cmsghdr>()))
+            as ::c_uint
+    }
+
+    pub fn CMSG_LEN(len: ::c_uint) -> ::c_uint {
+        (CMSG_ALIGN(::mem::size_of::<cmsghdr>()) + len as ::size_t) as ::c_uint
+    }
+}
+
+fn __CMSG_LEN(cmsg: *const cmsghdr) -> ::ssize_t {
+    ((unsafe { (*cmsg).cmsg_len as ::size_t } + ::mem::size_of::<::c_long>()
+        - 1)
+        & !(::mem::size_of::<::c_long>() - 1)) as ::ssize_t
+}
+
+fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar {
+    (unsafe { cmsg.offset(__CMSG_LEN(cmsg)) }) as *mut c_uchar
+}
+
+fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar {
+    unsafe {
+        (*mhdr).msg_control.offset((*mhdr).msg_controllen as isize)
+    }.cast()
 }
 
 // EXTERN_FN
-- 
GitLab