summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2017-12-11 16:38:49 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2017-12-11 16:38:49 +0000
commit291d618322a360e2b3ac99ca7c1fde19ba6b4b2c (patch)
treebde0850d79922887cbf845c7a67d38510cf88af0 /src/sys
parentb957a7a801635cbf5b7b4f8bae67108a7117e0fd (diff)
parent111950df8f21023e80249bb67c0f9cb8d0b2342f (diff)
downloadnix-291d618322a360e2b3ac99ca7c1fde19ba6b4b2c.zip
Merge #814
814: Misc cleanup r=Susurrus a=Susurrus Add more traits to the various datatypes in `nix`. Also try to utilize more `libc` types where appropriate. This is still WIP because: * Looking for feedback on ba2d85bc. Does it make sense for bitflags structs to have `Ord` & `PartialOrd` derived for them? * Need to implement a newtype wrapper around `libc::linger` with both a `new()` constructor and getters. Additionally this needs manual implementations of `Eq`, `PartialEq`, `Debug` (I've been skipping manually implementing `Hash` for now. * In 2b3fb11a46 I need to implement newtype wrappers around `ip_mreq` and `ipv6_mreq` that have `new()` constructors and field getters. Additionally they need manual implementations of `Eq`, `PartialEq`, `Debug` (I've been skipping manually implementing `Hash` for now. This commit also needs a CHANGELOG entry. * ed79cfbc needs a CHANGELOG entry because its variants names have changed with the switch to using `libc_bitflags!`.
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/epoll.rs2
-rw-r--r--src/sys/signalfd.rs2
-rw-r--r--src/sys/socket/mod.rs153
-rw-r--r--src/sys/socket/multicast.rs40
-rw-r--r--src/sys/socket/sockopt.rs32
-rw-r--r--src/sys/statvfs.rs26
6 files changed, 157 insertions, 98 deletions
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index 43a543ab..c6c2eab3 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -28,7 +28,7 @@ libc_bitflags!(
}
);
-#[derive(Clone, Copy, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
pub enum EpollOp {
EpollCtlAdd = libc::EPOLL_CTL_ADD,
diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs
index 7ea09ee3..0da9187e 100644
--- a/src/sys/signalfd.rs
+++ b/src/sys/signalfd.rs
@@ -79,7 +79,7 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// Err(err) => (), // some error happend
/// }
/// ```
-#[derive(Debug)]
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct SignalFd(RawFd);
impl SignalFd {
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index bd8764b7..6292bb02 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -4,15 +4,14 @@
use {Error, Result};
use errno::Errno;
use features;
-use libc::{self, c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
-use std::{mem, ptr, slice};
+use libc::{self, c_void, c_int, socklen_t, size_t};
+use std::{fmt, mem, ptr, slice};
use std::os::unix::io::RawFd;
use sys::time::TimeVal;
use sys::uio::IoVec;
mod addr;
mod ffi;
-mod multicast;
pub mod sockopt;
/*
@@ -34,22 +33,14 @@ pub use self::addr::{
pub use ::sys::socket::addr::netlink::NetlinkAddr;
pub use libc::{
- in_addr,
- in6_addr,
+ sa_family_t,
sockaddr,
sockaddr_in,
sockaddr_in6,
+ sockaddr_storage,
sockaddr_un,
- sa_family_t,
-};
-
-pub use self::multicast::{
- ip_mreq,
- ipv6_mreq,
};
-pub use libc::sockaddr_storage;
-
/// These constants are used to specify the communication semantics
/// when creating a socket with [`socket()`](fn.socket.html)
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -77,6 +68,7 @@ pub enum SockType {
/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
/// to specify the protocol to use.
#[repr(i32)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SockProtocol {
/// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
Tcp = libc::IPPROTO_TCP,
@@ -174,6 +166,121 @@ libc_bitflags!{
}
}
+cfg_if! {
+ if #[cfg(all(target_os = "linux", not(target_arch = "arm")))] {
+ /// Unix credentials of the sending process.
+ ///
+ /// This struct is used with the `SO_PEERCRED` ancillary message for UNIX sockets.
+ #[repr(C)]
+ #[derive(Clone, Copy)]
+ pub struct UnixCredentials(libc::ucred);
+
+ impl UnixCredentials {
+ /// Returns the process identifier
+ pub fn pid(&self) -> libc::pid_t {
+ self.0.pid
+ }
+
+ /// Returns the user identifier
+ pub fn uid(&self) -> libc::uid_t {
+ self.0.uid
+ }
+
+ /// Returns the group identifier
+ pub fn gid(&self) -> libc::gid_t {
+ self.0.gid
+ }
+ }
+
+ impl PartialEq for UnixCredentials {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.pid == other.0.pid && self.0.uid == other.0.uid && self.0.gid == other.0.gid
+ }
+ }
+ impl Eq for UnixCredentials {}
+
+ impl fmt::Debug for UnixCredentials {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("UnixCredentials")
+ .field("pid", &self.0.pid)
+ .field("uid", &self.0.uid)
+ .field("gid", &self.0.gid)
+ .finish()
+ }
+ }
+ }
+}
+
+/// Request for multicast socket operations
+///
+/// This is a wrapper type around `ip_mreq`.
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct IpMembershipRequest(libc::ip_mreq);
+
+impl IpMembershipRequest {
+ /// Instantiate a new `IpMembershipRequest`
+ ///
+ /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface.
+ pub fn new(group: Ipv4Addr, interface: Option<Ipv4Addr>) -> Self {
+ IpMembershipRequest(libc::ip_mreq {
+ imr_multiaddr: group.0,
+ imr_interface: interface.unwrap_or(Ipv4Addr::any()).0,
+ })
+ }
+}
+
+impl PartialEq for IpMembershipRequest {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.imr_multiaddr.s_addr == other.0.imr_multiaddr.s_addr
+ && self.0.imr_interface.s_addr == other.0.imr_interface.s_addr
+ }
+}
+impl Eq for IpMembershipRequest {}
+
+impl fmt::Debug for IpMembershipRequest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("IpMembershipRequest")
+ .field("imr_multiaddr", &self.0.imr_multiaddr.s_addr)
+ .field("imr_interface", &self.0.imr_interface.s_addr)
+ .finish()
+ }
+}
+
+/// Request for ipv6 multicast socket operations
+///
+/// This is a wrapper type around `ipv6_mreq`.
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
+
+impl Ipv6MembershipRequest {
+ /// Instantiate a new `Ipv6MembershipRequest`
+ pub fn new(group: Ipv6Addr) -> Self {
+ Ipv6MembershipRequest(libc::ipv6_mreq {
+ ipv6mr_multiaddr: group.0,
+ ipv6mr_interface: 0,
+ })
+ }
+}
+
+impl PartialEq for Ipv6MembershipRequest {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.ipv6mr_multiaddr.s6_addr == other.0.ipv6mr_multiaddr.s6_addr &&
+ self.0.ipv6mr_interface == other.0.ipv6mr_interface
+ }
+}
+impl Eq for Ipv6MembershipRequest {}
+
+impl fmt::Debug for Ipv6MembershipRequest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Ipv6MembershipRequest")
+ .field("ipv6mr_multiaddr", &self.0.ipv6mr_multiaddr.s6_addr)
+ .field("ipv6mr_interface", &self.0.ipv6mr_interface)
+ .finish()
+ }
+}
+
/// Copy the in-memory representation of src into the byte slice dst,
/// updating the slice to point to the remainder of dst only. Unsafe
/// because it exposes all bytes in src, which may be UB if some of them
@@ -799,21 +906,6 @@ pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
Errno::result(ret).map(|r| r as usize)
}
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub struct linger {
- pub l_onoff: c_int,
- pub l_linger: c_int
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ucred {
- pid: pid_t,
- uid: uid_t,
- gid: gid_t,
-}
-
/*
*
* ===== Socket Options =====
@@ -825,13 +917,14 @@ pub struct ucred {
///
/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
#[repr(i32)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SockLevel {
Socket = libc::SOL_SOCKET,
Tcp = libc::IPPROTO_TCP,
Ip = libc::IPPROTO_IP,
Ipv6 = libc::IPPROTO_IPV6,
Udp = libc::IPPROTO_UDP,
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
Netlink = libc::SOL_NETLINK,
}
@@ -938,7 +1031,7 @@ pub unsafe fn sockaddr_storage_to_addr(
}
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Shutdown {
/// Further receptions will be disallowed.
Read,
diff --git a/src/sys/socket/multicast.rs b/src/sys/socket/multicast.rs
deleted file mode 100644
index 7561bb35..00000000
--- a/src/sys/socket/multicast.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use super::addr::{Ipv4Addr, Ipv6Addr};
-use libc::{in_addr, in6_addr, c_uint};
-use std::fmt;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct ip_mreq {
- pub imr_multiaddr: in_addr,
- pub imr_interface: in_addr,
-}
-
-impl fmt::Debug for ip_mreq {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- write!(fmt, "ip_mreq {{ imr_multiaddr: {{ s_addr: 0x{:x} }}, imr_interface: {{ s_addr: 0x{:x} }} }}",
- self.imr_multiaddr.s_addr, self.imr_interface.s_addr)
- }
-}
-
-impl ip_mreq {
- pub fn new(group: Ipv4Addr, interface: Option<Ipv4Addr>) -> ip_mreq {
- ip_mreq {
- imr_multiaddr: group.0,
- imr_interface: interface.unwrap_or(Ipv4Addr::any()).0
- }
- }
-}
-
-pub struct ipv6_mreq {
- pub ipv6mr_multiaddr: in6_addr,
- pub ipv6mr_interface: c_uint,
-}
-
-impl ipv6_mreq {
- pub fn new(group: Ipv6Addr) -> ipv6_mreq {
- ipv6_mreq {
- ipv6mr_multiaddr: group.0,
- ipv6mr_interface: 0,
- }
- }
-}
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 4741ec66..065d3101 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -132,17 +132,23 @@ macro_rules! sockopt_impl {
sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool);
sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool);
sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool);
-sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, super::linger);
-sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::ip_mreq);
-sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::ip_mreq);
-#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq);
-#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq);
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::ipv6_mreq);
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::ipv6_mreq);
+sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger);
+sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::IpMembershipRequest);
+sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::IpMembershipRequest);
+cfg_if! {
+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest);
+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
+ } else if #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))] {
+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest);
+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest);
+ }
+}
sockopt_impl!(Both, IpMulticastTtl, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8);
sockopt_impl!(Both, IpMulticastLoop, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool);
sockopt_impl!(Both, ReceiveTimeout, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal);
@@ -152,7 +158,7 @@ sockopt_impl!(Both, OobInline, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool);
sockopt_impl!(GetOnly, SocketError, libc::SOL_SOCKET, libc::SO_ERROR, i32);
sockopt_impl!(Both, KeepAlive, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool);
#[cfg(all(target_os = "linux", not(target_arch="arm")))]
-sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::ucred);
+sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials);
#[cfg(any(target_os = "macos",
target_os = "ios"))]
sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
@@ -384,7 +390,7 @@ mod test {
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
assert_eq!(a_cred, b_cred);
- assert!(a_cred.pid != 0);
+ assert!(a_cred.pid() != 0);
}
#[test]
diff --git a/src/sys/statvfs.rs b/src/sys/statvfs.rs
index 0a0dab7f..fbd0570e 100644
--- a/src/sys/statvfs.rs
+++ b/src/sys/statvfs.rs
@@ -10,45 +10,45 @@ use libc::{self, c_ulong};
use {Result, NixPath};
use errno::Errno;
-bitflags!(
+libc_bitflags!(
/// File system mount Flags
#[repr(C)]
#[derive(Default)]
pub struct FsFlags: c_ulong {
/// Read Only
- const RDONLY = libc::ST_RDONLY;
+ ST_RDONLY;
/// Do not allow the set-uid bits to have an effect
- const NOSUID = libc::ST_NOSUID;
+ ST_NOSUID;
/// Do not interpret character or block-special devices
#[cfg(any(target_os = "android", target_os = "linux"))]
- const NODEV = libc::ST_NODEV;
+ ST_NODEV;
/// Do not allow execution of binaries on the filesystem
#[cfg(any(target_os = "android", target_os = "linux"))]
- const NOEXEC = libc::ST_NOEXEC;
+ ST_NOEXEC;
/// All IO should be done synchronously
#[cfg(any(target_os = "android", target_os = "linux"))]
- const SYNCHRONOUS = libc::ST_SYNCHRONOUS;
+ ST_SYNCHRONOUS;
/// Allow mandatory locks on the filesystem
#[cfg(any(target_os = "android", target_os = "linux"))]
- const MANDLOCK = libc::ST_MANDLOCK;
+ ST_MANDLOCK;
/// Write on file/directory/symlink
#[cfg(any(target_os = "android", target_os = "linux"))]
- const WRITE = libc::ST_WRITE;
+ ST_WRITE;
/// Append-only file
#[cfg(any(target_os = "android", target_os = "linux"))]
- const APPEND = libc::ST_APPEND;
+ ST_APPEND;
/// Immutable file
#[cfg(any(target_os = "android", target_os = "linux"))]
- const IMMUTABLE = libc::ST_IMMUTABLE;
+ ST_IMMUTABLE;
/// Do not update access times on files
#[cfg(any(target_os = "android", target_os = "linux"))]
- const NOATIME = libc::ST_NOATIME;
+ ST_NOATIME;
/// Do not update access times on files
#[cfg(any(target_os = "android", target_os = "linux"))]
- const NODIRATIME = libc::ST_NODIRATIME;
+ ST_NODIRATIME;
/// Update access time relative to modify/change time
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))]
- const RELATIME = libc::ST_RELATIME;
+ ST_RELATIME;
}
);