From 1e48b13948a2d5c6459d0d57f3fdb5395a4d2b4d Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 4 May 2025 09:32:10 -0600 Subject: [PATCH] Debug recvmsg on redox --- src/header/sys_socket/mod.rs | 61 ++++++++++++++++++++++++++++++++++++ src/platform/redox/socket.rs | 20 ++++++++++-- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs index 58f9e5912a..527afa03ba 100644 --- a/src/header/sys_socket/mod.rs +++ b/src/header/sys_socket/mod.rs @@ -24,6 +24,7 @@ pub struct linger { pub extern "C" fn _cbindgen_export_linger(linger: linger) {} #[repr(C)] +#[derive(Debug)] pub struct msghdr { pub msg_name: *mut c_void, pub msg_namelen: socklen_t, @@ -35,6 +36,7 @@ pub struct msghdr { } #[repr(C)] +#[derive(Debug)] pub struct cmsghdr { pub cmsg_len: size_t, pub cmsg_level: c_int, @@ -71,6 +73,65 @@ pub struct sockaddr_storage { __ss_align: usize, } +// These must match C macros in include/bits/sys/socket.h { +pub unsafe extern "C" fn __CMSG_LEN(cmsg: *const cmsghdr) -> ssize_t { + ((unsafe { (*cmsg).cmsg_len as size_t } + mem::size_of::() - 1) + & !(mem::size_of::() - 1)) as ssize_t +} + +pub unsafe extern "C" fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar { + unsafe { (cmsg as *mut c_uchar).offset(__CMSG_LEN(cmsg)) } +} + +pub unsafe extern "C" fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar { + unsafe { ((*mhdr).msg_control as *mut c_uchar).offset((*mhdr).msg_controllen as isize) } +} + +pub unsafe extern "C" fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + unsafe { (cmsg as *mut c_uchar).offset(CMSG_ALIGN(mem::size_of::()) as isize) } +} + +pub unsafe extern "C" fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return CMSG_FIRSTHDR(mhdr); + }; + + unsafe { + let next = cmsg as usize + + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(mem::size_of::()); + let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut cmsghdr + } else { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr + } + } +} + +pub unsafe extern "C" fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + unsafe { + if (*mhdr).msg_controllen as usize >= mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } +} + +pub unsafe extern "C" fn CMSG_ALIGN(len: size_t) -> size_t { + (len + mem::size_of::() - 1) & !(mem::size_of::() - 1) +} + +pub unsafe extern "C" fn CMSG_SPACE(len: c_uint) -> c_uint { + (CMSG_ALIGN(len as size_t) + CMSG_ALIGN(mem::size_of::())) as c_uint +} + +pub unsafe extern "C" fn CMSG_LEN(length: c_uint) -> c_uint { + (CMSG_ALIGN(mem::size_of::()) + length as usize) as c_uint +} +// } These must match C macros in include/bits/sys/socket.h + #[no_mangle] pub unsafe extern "C" fn accept( socket: c_int, diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index f28f23fea5..1e571f4bfb 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -14,7 +14,9 @@ use crate::{ errno::{EAFNOSUPPORT, EDOM, EFAULT, EINVAL, ENOSYS, EOPNOTSUPP, EPROTONOSUPPORT}, netinet_in::{in_addr, in_port_t, sockaddr_in}, string::strnlen, - sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t}, + sys_socket::{ + constants::*, msghdr, sa_family_t, sockaddr, socklen_t, CMSG_FIRSTHDR, CMSG_NXTHDR, + }, sys_time::timeval, sys_un::sockaddr_un, }, @@ -310,7 +312,21 @@ impl PalSocket for Sys { unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result { //TODO: implement recvfrom with recvmsg - eprintln!("recvmsg not implemented on redox"); + eprintln!( + "recvmsg({}, {:p}, {:#x}) not implemented on redox", + socket, msg, flags + ); + if !msg.is_null() { + let msg = &*msg; + eprintln!("{:#x?}", msg); + if !msg.msg_control.is_null() { + let mut cmsg = CMSG_FIRSTHDR(msg); + while !cmsg.is_null() { + eprintln!("{:#x?}", *cmsg); + cmsg = CMSG_NXTHDR(msg, cmsg); + } + } + } Err(Errno(ENOSYS)) }