Skip to content

Commit

Permalink
Add Fuchsia support and CI
Browse files Browse the repository at this point in the history
In general, feature support is identical to Linux.
  • Loading branch information
tamird authored and Thomasdezeeuw committed Dec 25, 2020
1 parent 1b77162 commit efa912a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
target: [x86_64-unknown-redox]
target: [x86_64-unknown-redox, x86_64-fuchsia]
steps:
- uses: actions/checkout@master
- name: Install Rust
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ impl TcpKeepalive {
feature = "all",
any(
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
Expand All @@ -390,6 +391,7 @@ impl TcpKeepalive {
feature = "all",
any(
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
Expand Down
6 changes: 6 additions & 0 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ impl Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -201,6 +202,7 @@ impl Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand Down Expand Up @@ -580,6 +582,7 @@ fn set_common_type(ty: Type) -> Type {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -604,6 +607,7 @@ fn set_common_flags(socket: Socket) -> io::Result<Socket> {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand Down Expand Up @@ -1217,6 +1221,7 @@ impl Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -1241,6 +1246,7 @@ impl Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand Down
92 changes: 48 additions & 44 deletions src/sys/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// except according to those terms.

use std::cmp::min;
#[cfg(all(feature = "all", target_os = "linux"))]
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
use std::ffi::{CStr, CString};
#[cfg(not(target_os = "redox"))]
use std::io::IoSlice;
Expand Down Expand Up @@ -90,6 +90,7 @@ pub(crate) use libc::{
feature = "all",
any(
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
Expand Down Expand Up @@ -142,6 +143,7 @@ type IovLen = usize;
all(target_os = "linux", target_env = "musl"),
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "netbsd",
target_os = "openbsd",
Expand All @@ -159,8 +161,8 @@ impl Domain {
///
/// # Notes
///
/// This function is only available on Linux.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub const PACKET: Domain = Domain(libc::AF_PACKET);
}

Expand All @@ -169,7 +171,7 @@ impl_debug!(
libc::AF_INET,
libc::AF_INET6,
libc::AF_UNIX,
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "fuchsia", target_os = "linux"))]
libc::AF_PACKET,
libc::AF_UNSPEC, // = 0.
);
Expand All @@ -180,14 +182,15 @@ impl Type {
///
/// # Notes
///
/// This function is only available on Android, DragonFlyBSD, FreeBSD,
/// Linux, NetBSD and OpenBSD.
/// This function is only available on Android, DragonFlyBSD, Fuchsia,
/// FreeBSD, Linux, NetBSD and OpenBSD.
#[cfg(all(
feature = "all",
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -202,14 +205,15 @@ impl Type {
///
/// # Notes
///
/// This function is only available on Android, DragonFlyBSD, FreeBSD,
/// Linux, NetBSD and OpenBSD.
/// This function is only available on Android, DragonFlyBSD, Fuchsia,
/// FreeBSD, Linux, NetBSD and OpenBSD.
#[cfg(all(
feature = "all",
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -224,6 +228,7 @@ impl Type {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -248,6 +253,7 @@ impl_debug!(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd"
Expand All @@ -257,6 +263,7 @@ impl_debug!(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd"
Expand Down Expand Up @@ -519,15 +526,12 @@ fn recvmsg(
} else {
size_of::<libc::sockaddr_storage>() as libc::socklen_t
};
let mut msg = libc::msghdr {
msg_name: msg_name.cast(),
msg_namelen,
msg_iov: bufs.as_mut_ptr().cast(),
msg_iovlen: min(bufs.len(), IovLen::MAX as usize) as IovLen,
msg_control: ptr::null_mut(),
msg_controllen: 0,
msg_flags: 0,
};
// libc::msghdr contains unexported padding fields on Fuchsia.
let mut msg: libc::msghdr = unsafe { mem::zeroed() };
msg.msg_name = msg_name.cast();
msg.msg_namelen = msg_namelen;
msg.msg_iov = bufs.as_mut_ptr().cast();
msg.msg_iovlen = min(bufs.len(), IovLen::MAX as usize) as IovLen;
syscall!(recvmsg(fd, &mut msg, flags))
.map(|n| (n as usize, msg.msg_namelen, RecvFlags(msg.msg_flags)))
}
Expand Down Expand Up @@ -578,19 +582,16 @@ fn sendmsg(
bufs: &[IoSlice<'_>],
flags: c_int,
) -> io::Result<usize> {
let mut msg = libc::msghdr {
// Safety: we're creating a `*mut` pointer from a reference, which is UB
// once actually used. However the OS should not write to it in the
// `sendmsg` system call.
msg_name: (msg_name as *mut sockaddr_storage).cast(),
msg_namelen,
// Safety: Same as above about `*const` -> `*mut`.
msg_iov: bufs.as_ptr() as *mut _,
msg_iovlen: min(bufs.len(), IovLen::MAX as usize) as IovLen,
msg_control: ptr::null_mut(),
msg_controllen: 0,
msg_flags: 0,
};
// libc::msghdr contains unexported padding fields on Fuchsia.
let mut msg: libc::msghdr = unsafe { mem::zeroed() };
// Safety: we're creating a `*mut` pointer from a reference, which is UB
// once actually used. However the OS should not write to it in the
// `sendmsg` system call.
msg.msg_name = (msg_name as *mut sockaddr_storage).cast();
msg.msg_namelen = msg_namelen;
// Safety: Same as above about `*const` -> `*mut`.
msg.msg_iov = bufs.as_ptr() as *mut _;
msg.msg_iovlen = min(bufs.len(), IovLen::MAX as usize) as IovLen;
syscall!(sendmsg(fd, &mut msg, flags)).map(|n| n as usize)
}

Expand Down Expand Up @@ -651,6 +652,7 @@ pub(crate) fn set_tcp_keepalive(fd: Socket, keepalive: &TcpKeepalive) -> io::Res
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand Down Expand Up @@ -778,6 +780,7 @@ impl crate::Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand All @@ -792,6 +795,7 @@ impl crate::Socket {
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
Expand Down Expand Up @@ -881,9 +885,9 @@ impl crate::Socket {
/// This value gets the socket mark field for each packet sent through
/// this socket.
///
/// This function is only available on Linux and requires the
/// `CAP_NET_ADMIN` capability.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux. On Linux it
/// requires the `CAP_NET_ADMIN` capability.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn mark(&self) -> io::Result<u32> {
unsafe {
getsockopt::<c_int>(self.inner, libc::SOL_SOCKET, libc::SO_MARK).map(|mark| mark as u32)
Expand All @@ -896,9 +900,9 @@ impl crate::Socket {
/// this socket. Changing the mark can be used for mark-based routing
/// without netfilter or for packet filtering.
///
/// This function is only available on Linux and requires the
/// `CAP_NET_ADMIN` capability.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux. On Linux it
/// requires the `CAP_NET_ADMIN` capability.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn set_mark(&self, mark: u32) -> io::Result<()> {
unsafe { setsockopt::<c_int>(self.inner, libc::SOL_SOCKET, libc::SO_MARK, mark as c_int) }
}
Expand All @@ -907,8 +911,8 @@ impl crate::Socket {
///
/// This value gets the socket binded device's interface name.
///
/// This function is only available on Linux.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn device(&self) -> io::Result<Option<CString>> {
// TODO: replace with `MaybeUninit::uninit_array` once stable.
let mut buf: [MaybeUninit<u8>; libc::IFNAMSIZ] =
Expand Down Expand Up @@ -952,8 +956,8 @@ impl crate::Socket {
///
/// If `interface` is `None` or an empty string it removes the binding.
///
/// This function is only available on Linux.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn bind_device(&self, interface: Option<&CStr>) -> io::Result<()> {
let (value, len) = if let Some(interface) = interface {
(interface.as_ptr(), interface.to_bytes_with_nul().len())
Expand Down Expand Up @@ -1014,10 +1018,10 @@ impl crate::Socket {
///
/// For more information about this option, see [`set_freebind`].
///
/// This function is only available on Linux.
/// This function is only available on Fuchsia and Linux.
///
/// [`set_freebind`]: Socket::set_freebind
#[cfg(all(feature = "all", target_os = "linux"))]
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn freebind(&self) -> io::Result<bool> {
unsafe {
getsockopt::<c_int>(self.inner, libc::SOL_SOCKET, libc::IP_FREEBIND)
Expand All @@ -1033,8 +1037,8 @@ impl crate::Socket {
/// dynamic IP address to be up at the time that the application is trying
/// to bind to it.
///
/// This function is only available on Linux.
#[cfg(all(feature = "all", target_os = "linux"))]
/// This function is only available on Fuchsia and Linux.
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
pub fn set_freebind(&self, reuse: bool) -> io::Result<()> {
unsafe {
setsockopt(
Expand Down
Loading

0 comments on commit efa912a

Please sign in to comment.