diff --git a/src/header/fcntl/redox.rs b/src/header/fcntl/redox.rs index efe7beed58..de3ebe4db2 100644 --- a/src/header/fcntl/redox.rs +++ b/src/header/fcntl/redox.rs @@ -22,3 +22,5 @@ pub const O_SYMLINK: c_int = 0x4000_0000; pub const O_NOFOLLOW: c_int = -0x8000_0000; pub const FD_CLOEXEC: c_int = 0x0100_0000; + +pub const O_NOCTTY: c_int = 0x00000200; diff --git a/src/header/netinet_in/cbindgen.toml b/src/header/netinet_in/cbindgen.toml index 2467174a3b..fcc704f4bb 100644 --- a/src/header/netinet_in/cbindgen.toml +++ b/src/header/netinet_in/cbindgen.toml @@ -7,7 +7,7 @@ no_includes = true cpp_compat = true [export] -include = ["sockaddr_in6", "sockaddr_in", "ipv6_mreq"] +include = ["sockaddr_in6", "sockaddr_in", "ipv6_mreq", "ip_mreq", "ip_mreq_source"] [enum] prefix_with_name = true diff --git a/src/header/netinet_in/mod.rs b/src/header/netinet_in/mod.rs index 72a4f622f3..721d7a7d72 100644 --- a/src/header/netinet_in/mod.rs +++ b/src/header/netinet_in/mod.rs @@ -60,6 +60,20 @@ pub const IPPROTO_IPV6: u8 = 41; pub const IPPROTO_RAW: u8 = 0xff; pub const IPPROTO_MAX: u8 = 0xff; +pub const IP_TTL: c_int = 2; +pub const IPV6_UNICAST_HOPS: c_int = 16; +pub const IPV6_MULTICAST_IF: c_int = 17; +pub const IPV6_MULTICAST_HOPS: c_int = 18; +pub const IPV6_MULTICAST_LOOP: c_int = 19; +pub const IPV6_ADD_MEMBERSHIP: c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: c_int = 21; +pub const IPV6_V6ONLY: c_int = 26; +pub const IP_MULTICAST_IF: c_int = 32; +pub const IP_MULTICAST_TTL: c_int = 33; +pub const IP_MULTICAST_LOOP: c_int = 34; +pub const IP_ADD_MEMBERSHIP: c_int = 35; +pub const IP_DROP_MEMBERSHIP: c_int = 36; + pub const INADDR_ANY: u32 = 0; // Can't use in_addr_t alias because cbindgen :( pub const INADDR_BROADCAST: u32 = 0xFFFF_FFFF; // Can't use core::u32::MAX because cbindgen :( pub const INADDR_NONE: u32 = 0xFFFF_FFFF; @@ -70,6 +84,19 @@ pub const INADDR_ALLHOSTS_GROUP: u32 = 0xE000_0001; pub const INADDR_ALLRTRS_GROUP: u32 = 0xE000_0002; pub const INADDR_MAX_LOCAL_GROUP: u32 = 0xE000_00FF; +#[repr(C)] +pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + pub imr_sourceaddr: in_addr, +} + +#[repr(C)] +pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, +} + #[no_mangle] pub static in6addr_any: in6_addr = in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], diff --git a/src/header/sys_socket/constants.rs b/src/header/sys_socket/constants.rs index f5e794a1d8..89af160539 100644 --- a/src/header/sys_socket/constants.rs +++ b/src/header/sys_socket/constants.rs @@ -51,6 +51,11 @@ pub const MSG_TRUNC: c_int = 32; pub const MSG_DONTWAIT: c_int = 64; pub const MSG_WAITALL: c_int = 256; +pub const IP_ADD_SOURCE_MEMBERSHIP: c_int = 70; +pub const IP_DROP_SOURCE_MEMBERSHIP: c_int = 71; +pub const MCAST_JOIN_SOURCE_GROUP: c_int = 46; +pub const MCAST_LEAVE_SOURCE_GROUP: c_int = 47; + pub const AF_INET: c_int = 2; pub const AF_INET6: c_int = 10; pub const AF_LOCAL: c_int = AF_UNIX; @@ -66,3 +71,5 @@ pub const PF_UNSPEC: c_int = 0; pub const SHUT_RD: c_int = 0; pub const SHUT_RDWR: c_int = 2; pub const SHUT_WR: c_int = 1; + +pub const SCM_RIGHTS: c_int = 1; diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs index 576a8fb33d..659eceac32 100644 --- a/src/header/sys_socket/mod.rs +++ b/src/header/sys_socket/mod.rs @@ -1,6 +1,6 @@ //! socket implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xns/syssocket.h.html -use core::ptr; +use core::{mem, ptr}; use crate::{ error::ResultExt, @@ -34,6 +34,13 @@ pub struct msghdr { pub msg_flags: c_int, } +#[repr(C)] +pub struct cmsghdr { + pub cmsg_len: size_t, + pub cmsg_level: c_int, + pub cmsg_type: c_int, +} + #[repr(C)] #[derive(Default)] pub struct sockaddr { @@ -41,6 +48,72 @@ pub struct sockaddr { pub sa_data: [c_char; 14], } +#[no_mangle] +pub unsafe extern "C" fn CMSG_ALIGN(len: size_t) -> size_t { + (len + mem::size_of::() - 1) & !(mem::size_of::() - 1) +} + +#[no_mangle] +pub unsafe extern "C" fn CMSG_LEN(length: c_uint) -> c_uint { + (CMSG_ALIGN(mem::size_of::()) + length as usize) as c_uint +} + +#[no_mangle] +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 +} + +#[no_mangle] +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 + } + } +} + +#[no_mangle] +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 + } + } +} + +#[no_mangle] +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) } +} + +#[no_mangle] +pub fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar { + unsafe { (*mhdr).msg_control.offset((*mhdr).msg_controllen as isize) }.cast() +} + +#[no_mangle] +pub 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 +} + +#[no_mangle] +pub fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar { + (unsafe { cmsg.offset(__CMSG_LEN(cmsg)) }) as *mut c_uchar +} + #[no_mangle] pub unsafe extern "C" fn accept( socket: c_int, diff --git a/src/header/unistd/sysconf.rs b/src/header/unistd/sysconf.rs index 15074a5852..5e13346019 100644 --- a/src/header/unistd/sysconf.rs +++ b/src/header/unistd/sysconf.rs @@ -19,6 +19,9 @@ pub const _SC_PAGESIZE: c_int = 30; pub const _SC_PAGE_SIZE: c_int = 30; // ... pub const _SC_RE_DUP_MAX: c_int = 44; + +pub const _SC_NPROCESSORS_ONLN: c_int = 58; + // ... pub const _SC_GETGR_R_SIZE_MAX: c_int = 69; pub const _SC_GETPW_R_SIZE_MAX: c_int = 70; @@ -52,6 +55,7 @@ pub extern "C" fn sysconf(name: c_int) -> c_long { _SC_TTY_NAME_MAX => 32, _SC_SYMLOOP_MAX => -1, _SC_HOST_NAME_MAX => 64, + _SC_NPROCESSORS_ONLN => 1, _ => { platform::ERRNO.set(errno::EINVAL); -1