Skip to content

Commit

Permalink
Merge #814
Browse files Browse the repository at this point in the history
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 ba2d85b. 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 2b3fb11 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.
  * ed79cfb needs a CHANGELOG entry because its variants names have changed with the switch to using `libc_bitflags!`.
  • Loading branch information
bors[bot] committed Dec 11, 2017
2 parents b957a7a + 111950d commit 291d618
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 136 deletions.
16 changes: 14 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#739](https://github.com/nix-rust/nix/pull/739))
- Expose `signalfd` module on Android as well.
([#739](https://github.com/nix-rust/nix/pull/739))
- Added nix::sys::ptrace::detach.
- Added nix::sys::ptrace::detach.
([#749](https://github.com/nix-rust/nix/pull/749))
- Added timestamp socket control message variant:
`nix::sys::socket::ControlMessage::ScmTimestamp`
Expand All @@ -48,6 +48,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added the `from_raw()` method to `WaitStatus` for converting raw status values
to `WaitStatus` independent of syscalls.
([#741](https://github.com/nix-rust/nix/pull/741))
- Added more standard trait implementations for various types.
([#814](https://github.com/nix-rust/nix/pull/814))

### Changed
- Use native `pipe2` on all BSD targets. Users should notice no difference.
Expand Down Expand Up @@ -75,11 +77,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#731](https://github.com/nix-rust/nix/pull/731))
- Marked `pty::ptsname` function as `unsafe`
([#744](https://github.com/nix-rust/nix/pull/744))
- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
([#749](https://github.com/nix-rust/nix/pull/749))
- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715))
- Restricted `nix::sys::socket::UnixAddr::new_abstract` to Linux and Android only.
([#785](https://github.com/nix-rust/nix/pull/785))
- The `ucred` struct has been removed in favor of a `UserCredentials` struct that
contains only getters for its fields.
([#814](https://github.com/nix-rust/nix/pull/814))
- Both `ip_mreq` and `ipv6_mreq` have been replaced with `IpMembershipRequest` and
`Ipv6MembershipRequest`.
([#814](https://github.com/nix-rust/nix/pull/814))


### Fixed
Expand All @@ -95,6 +103,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#747](https://github.com/nix-rust/nix/pull/747))
- The `Errno` variants are no longer reexported from the `errno` module. `Errno` itself is no longer reexported from the
crate root and instead must be accessed using the `errno` module. ([#696](https://github.com/nix-rust/nix/pull/696))
- Removed `MS_VERBOSE`, `MS_NOSEC`, and `MS_BORN` from `MsFlags`. These
are internal kernel flags and should never have been exposed.
([#814](https://github.com/nix-rust/nix/pull/814))


## [0.9.0] 2017-07-23

Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

[Documentation (Releases)](https://docs.rs/nix/)

[Documentation (Development)](https://nix-rust.github.io/nix/nix/index.html)

Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin,
...). The goal is to not provide a 100% unified interface, but to unify
what can be while still providing platform specific APIs.
Expand Down
4 changes: 2 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ macro_rules! libc_enum {
}
) => {
$($attrs)*
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum $BitFlags {
$($entries)*
}
Expand All @@ -106,7 +106,7 @@ macro_rules! libc_enum {
}
) => {
$($attrs)*
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum $BitFlags {
$($entries)*
}
Expand Down
72 changes: 40 additions & 32 deletions src/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,47 @@ use libc;
use {Result, NixPath};
use errno::Errno;

bitflags!(
libc_bitflags!(
pub struct MsFlags: c_ulong {
const MS_RDONLY = libc::MS_RDONLY; // Mount read-only
const MS_NOSUID = libc::MS_NOSUID; // Ignore suid and sgid bits
const MS_NODEV = libc::MS_NODEV; // Disallow access to device special files
const MS_NOEXEC = libc::MS_NOEXEC; // Disallow program execution
const MS_SYNCHRONOUS = libc::MS_SYNCHRONOUS; // Writes are synced at once
const MS_REMOUNT = libc::MS_REMOUNT; // Alter flags of a mounted FS
const MS_MANDLOCK = libc::MS_MANDLOCK; // Allow mandatory locks on a FS
const MS_DIRSYNC = libc::MS_DIRSYNC; // Directory modifications are synchronous
const MS_NOATIME = libc::MS_NOATIME; // Do not update access times
const MS_NODIRATIME = libc::MS_NODIRATIME; // Do not update directory access times
const MS_BIND = libc::MS_BIND; // Linux 2.4.0 - Bind directory at different place
const MS_MOVE = libc::MS_MOVE;
const MS_REC = libc::MS_REC;
const MS_VERBOSE = 1 << 15; // Deprecated
const MS_SILENT = libc::MS_SILENT;
const MS_POSIXACL = libc::MS_POSIXACL;
const MS_UNBINDABLE = libc::MS_UNBINDABLE;
const MS_PRIVATE = libc::MS_PRIVATE;
const MS_SLAVE = libc::MS_SLAVE;
const MS_SHARED = libc::MS_SHARED;
const MS_RELATIME = libc::MS_RELATIME;
const MS_KERNMOUNT = libc::MS_KERNMOUNT;
const MS_I_VERSION = libc::MS_I_VERSION;
const MS_STRICTATIME = libc::MS_STRICTATIME;
const MS_NOSEC = 1 << 28;
const MS_BORN = 1 << 29;
const MS_ACTIVE = libc::MS_ACTIVE;
const MS_NOUSER = libc::MS_NOUSER;
const MS_RMT_MASK = libc::MS_RMT_MASK;
const MS_MGC_VAL = libc::MS_MGC_VAL;
const MS_MGC_MSK = libc::MS_MGC_MSK;
/// Mount read-only
MS_RDONLY;
/// Ignore suid and sgid bits
MS_NOSUID;
/// Disallow access to device special files
MS_NODEV;
/// Disallow program execution
MS_NOEXEC;
/// Writes are synced at once
MS_SYNCHRONOUS;
/// Alter flags of a mounted FS
MS_REMOUNT;
/// Allow mandatory locks on a FS
MS_MANDLOCK;
/// Directory modifications are synchronous
MS_DIRSYNC;
/// Do not update access times
MS_NOATIME;
/// Do not update directory access times
MS_NODIRATIME;
/// Linux 2.4.0 - Bind directory at different place
MS_BIND;
MS_MOVE;
MS_REC;
MS_SILENT;
MS_POSIXACL;
MS_UNBINDABLE;
MS_PRIVATE;
MS_SLAVE;
MS_SHARED;
MS_RELATIME;
MS_KERNMOUNT;
MS_I_VERSION;
MS_STRICTATIME;
MS_ACTIVE;
MS_NOUSER;
MS_RMT_MASK;
MS_MGC_VAL;
MS_MGC_MSK;
}
);

Expand Down
2 changes: 1 addition & 1 deletion src/sys/epoll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/sys/signalfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
153 changes: 123 additions & 30 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand All @@ -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)]
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 =====
Expand All @@ -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,
}

Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 291d618

Please sign in to comment.