diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2017-12-11 16:38:49 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2017-12-11 16:38:49 +0000 |
commit | 291d618322a360e2b3ac99ca7c1fde19ba6b4b2c (patch) | |
tree | bde0850d79922887cbf845c7a67d38510cf88af0 /src/sys | |
parent | b957a7a801635cbf5b7b4f8bae67108a7117e0fd (diff) | |
parent | 111950df8f21023e80249bb67c0f9cb8d0b2342f (diff) | |
download | nix-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.rs | 2 | ||||
-rw-r--r-- | src/sys/signalfd.rs | 2 | ||||
-rw-r--r-- | src/sys/socket/mod.rs | 153 | ||||
-rw-r--r-- | src/sys/socket/multicast.rs | 40 | ||||
-rw-r--r-- | src/sys/socket/sockopt.rs | 32 | ||||
-rw-r--r-- | src/sys/statvfs.rs | 26 |
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; } ); |