summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcin Mielniczuk <marmistrz.dev@zoho.eu>2017-08-03 10:32:44 +0200
committerMarcin Mielniczuk <marmistrz.dev@zoho.eu>2017-08-03 10:32:44 +0200
commitebcedb3bf98271fb77752acaec7a5c4990db578c (patch)
treee71f59ba68e4a672b865356e9f5ab0e54d7ed69b /src
parent9ad235c1e23e2bdf287b8f03550e6d54c4124db7 (diff)
parent607ab97ac64f597e78ab321aedd3063f8e040074 (diff)
downloadnix-ebcedb3bf98271fb77752acaec7a5c4990db578c.zip
Merge remote-tracking branch 'upstream/master' into ptrace-noreg
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs1
-rw-r--r--src/poll.rs82
-rw-r--r--src/sys/socket/addr.rs246
-rw-r--r--src/sys/socket/consts.rs437
-rw-r--r--src/sys/socket/mod.rs152
-rw-r--r--src/sys/socket/sockopt.rs79
6 files changed, 446 insertions, 551 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 3518efac..cadc7fb4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -39,7 +39,6 @@ pub mod mqueue;
pub mod pty;
-#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod poll;
pub mod net;
diff --git a/src/poll.rs b/src/poll.rs
index afc5bd9c..60c31ace 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -1,11 +1,20 @@
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::time::TimeSpec;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::signal::SigSet;
+use std::os::unix::io::RawFd;
use libc;
use {Errno, Result};
+/// This is a wrapper around `libc::pollfd`.
+///
+/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
+/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
+/// for a specific file descriptor.
+///
+/// After a call to `poll` or `ppoll`, the events that occured can be
+/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PollFd {
@@ -13,7 +22,9 @@ pub struct PollFd {
}
impl PollFd {
- pub fn new(fd: libc::c_int, events: EventFlags) -> PollFd {
+ /// Creates a new `PollFd` specifying the events of interest
+ /// for a given file descriptor.
+ pub fn new(fd: RawFd, events: EventFlags) -> PollFd {
PollFd {
pollfd: libc::pollfd {
fd: fd,
@@ -23,26 +34,82 @@ impl PollFd {
}
}
+ /// Returns the events that occured in the last call to `poll` or `ppoll`.
pub fn revents(&self) -> Option<EventFlags> {
EventFlags::from_bits(self.pollfd.revents)
}
}
libc_bitflags! {
+ /// These flags define the different events that can be monitored by `poll` and `ppoll`
pub flags EventFlags: libc::c_short {
+ /// There is data to read.
POLLIN,
+ /// There is some exceptional condition on the file descriptor.
+ ///
+ /// Possibilities include:
+ ///
+ /// * There is out-of-band data on a TCP socket (see
+ /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
+ /// * A pseudoterminal master in packet mode has seen a state
+ /// change on the slave (see
+ /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
+ /// * A cgroup.events file has been modified (see
+ /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
POLLPRI,
+ /// Writing is now possible, though a write larger that the
+ /// available space in a socket or pipe will still block (unless
+ /// `O_NONBLOCK` is set).
POLLOUT,
+ /// Equivalent to [`POLLIN`](constant.POLLIN.html)
POLLRDNORM,
+ /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
POLLWRNORM,
+ /// Priority band data can be read (generally unused on Linux).
POLLRDBAND,
+ /// Priority data may be written.
POLLWRBAND,
+ /// Error condition (only returned in
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
+ /// This bit is also set for a file descriptor referring to the
+ /// write end of a pipe when the read end has been closed.
POLLERR,
+ /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
+ /// Note that when reading from a channel such as a pipe or a stream
+ /// socket, this event merely indicates that the peer closed its
+ /// end of the channel. Subsequent reads from the channel will
+ /// return 0 (end of file) only after all outstanding data in the
+ /// channel has been consumed.
POLLHUP,
+ /// Invalid request: `fd` not open (only returned in
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
POLLNVAL,
}
}
+/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
+/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
+///
+/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
+/// The function will return as soon as any event occur for any of these `PollFd`s.
+///
+/// The `timeout` argument specifies the number of milliseconds that `poll()`
+/// should block waiting for a file descriptor to become ready. The call
+/// will block until either:
+///
+/// * a file descriptor becomes ready;
+/// * the call is interrupted by a signal handler; or
+/// * the timeout expires.
+///
+/// Note that the timeout interval will be rounded up to the system clock
+/// granularity, and kernel scheduling delays mean that the blocking
+/// interval may overrun by a small amount. Specifying a negative value
+/// in timeout means an infinite timeout. Specifying a timeout of zero
+/// causes `poll()` to return immediately, even if no file descriptors are
+/// ready.
pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
let res = unsafe {
libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
@@ -53,7 +120,14 @@ pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
Errno::result(res)
}
-#[cfg(any(target_os = "linux", target_os = "android"))]
+/// `ppoll()` allows an application to safely wait until either a file
+/// descriptor becomes ready or until a signal is caught.
+/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
+///
+/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
+/// with the `sigmask` argument.
+///
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index 5f8b130a..71001534 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -1,37 +1,204 @@
-use super::{consts, sa_family_t};
+use super::sa_family_t;
use {Errno, Error, Result, NixPath};
use libc;
use std::{fmt, hash, mem, net, ptr};
use std::ffi::OsStr;
use std::path::Path;
use std::os::unix::ffi::OsStrExt;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
use ::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
use std::os::unix::io::RawFd;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
use ::sys::socket::addr::sys_control::SysControlAddr;
-// TODO: uncomment out IpAddr functions: rust-lang/rfcs#988
-
-/*
- *
- * ===== AddressFamily =====
- *
- */
-
+/// These constants specify the protocol family to be used
+/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
#[repr(i32)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum AddressFamily {
- Unix = consts::AF_UNIX,
- Inet = consts::AF_INET,
- Inet6 = consts::AF_INET6,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- Netlink = consts::AF_NETLINK,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- Packet = consts::AF_PACKET,
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- System = consts::AF_SYSTEM,
+ /// Local communication (see [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html))
+ Unix = libc::AF_UNIX,
+ /// IPv4 Internet protocols (see [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Inet = libc::AF_INET,
+ /// IPv6 Internet protocols (see [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html))
+ Inet6 = libc::AF_INET6,
+ /// Kernel user interface device (see [`netlink(7)`](http://man7.org/linux/man-pages/man7/netlink.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Netlink = libc::AF_NETLINK,
+ /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Packet = libc::AF_PACKET,
+ /// KEXT Controls and Notifications
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ System = libc::AF_SYSTEM,
+ /// Amateur radio AX.25 protocol
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ax25 = libc::AF_AX25,
+ /// IPX - Novell protocols
+ Ipx = libc::AF_IPX,
+ /// AppleTalk
+ AppleTalk = libc::AF_APPLETALK,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ NetRom = libc::AF_NETROM,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Bridge = libc::AF_BRIDGE,
+ /// Access to raw ATM PVCs
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ AtmPvc = libc::AF_ATMPVC,
+ /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](http://man7.org/linux/man-pages/man7/x25.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ X25 = libc::AF_X25,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Rose = libc::AF_ROSE,
+ Decnet = libc::AF_DECnet,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ NetBeui = libc::AF_NETBEUI,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Security = libc::AF_SECURITY,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Key = libc::AF_KEY,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ash = libc::AF_ASH,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Econet = libc::AF_ECONET,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ AtmSvc = libc::AF_ATMSVC,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Rds = libc::AF_RDS,
+ Sna = libc::AF_SNA,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Irda = libc::AF_IRDA,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Pppox = libc::AF_PPPOX,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Wanpipe = libc::AF_WANPIPE,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Llc = libc::AF_LLC,
+ #[cfg(target_os = "linux")]
+ Ib = libc::AF_IB,
+ #[cfg(target_os = "linux")]
+ Mpls = libc::AF_MPLS,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Can = libc::AF_CAN,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Tipc = libc::AF_TIPC,
+ #[cfg(not(any(target_os = "ios", target_os = "macos")))]
+ Bluetooth = libc::AF_BLUETOOTH,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Iucv = libc::AF_IUCV,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ RxRpc = libc::AF_RXRPC,
+ Isdn = libc::AF_ISDN,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Phonet = libc::AF_PHONET,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ieee802154 = libc::AF_IEEE802154,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Caif = libc::AF_CAIF,
+ /// Interface to kernel crypto API
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Alg = libc::AF_ALG,
+ #[cfg(target_os = "linux")]
+ Nfc = libc::AF_NFC,
+ #[cfg(target_os = "linux")]
+ Vsock = libc::AF_VSOCK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ ImpLink = libc::AF_IMPLINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Pup = libc::AF_PUP,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Chaos = libc::AF_CHAOS,
+ #[cfg(any(target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Ns = libc::AF_NS,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Iso = libc::AF_ISO,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Datakit = libc::AF_DATAKIT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Ccitt = libc::AF_CCITT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Dli = libc::AF_DLI,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Lat = libc::AF_LAT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Hylink = libc::AF_HYLINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Link = libc::AF_LINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Coip = libc::AF_COIP,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Cnt = libc::AF_CNT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Natm = libc::AF_NATM,
}
#[derive(Copy)]
@@ -252,7 +419,7 @@ impl Ipv4Addr {
}
pub fn any() -> Ipv4Addr {
- Ipv4Addr(libc::in_addr { s_addr: consts::INADDR_ANY })
+ Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
}
pub fn octets(&self) -> [u8; 4] {
@@ -480,9 +647,9 @@ impl fmt::Display for UnixAddr {
pub enum SockAddr {
Inet(InetAddr),
Unix(UnixAddr),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
Netlink(NetlinkAddr),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SysControl(SysControlAddr),
}
@@ -495,12 +662,12 @@ impl SockAddr {
Ok(SockAddr::Unix(try!(UnixAddr::new(path))))
}
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
SockAddr::Netlink(NetlinkAddr::new(pid, groups))
}
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> {
SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a))
}
@@ -510,9 +677,9 @@ impl SockAddr {
SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
SockAddr::Unix(..) => AddressFamily::Unix,
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(..) => AddressFamily::Netlink,
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(..) => AddressFamily::System,
}
}
@@ -526,9 +693,9 @@ impl SockAddr {
SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t),
SockAddr::Inet(InetAddr::V6(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t),
SockAddr::Unix(UnixAddr(ref addr, len)) => (mem::transmute(addr), (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(NetlinkAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(SysControlAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<sys_control::sockaddr_ctl>() as libc::socklen_t),
}
}
@@ -543,7 +710,7 @@ impl PartialEq for SockAddr {
(SockAddr::Unix(ref a), SockAddr::Unix(ref b)) => {
a == b
}
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
(SockAddr::Netlink(ref a), SockAddr::Netlink(ref b)) => {
a == b
}
@@ -560,9 +727,9 @@ impl hash::Hash for SockAddr {
match *self {
SockAddr::Inet(ref a) => a.hash(s),
SockAddr::Unix(ref a) => a.hash(s),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(ref a) => a.hash(s),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(ref a) => a.hash(s),
}
}
@@ -579,15 +746,15 @@ impl fmt::Display for SockAddr {
match *self {
SockAddr::Inet(ref inet) => inet.fmt(f),
SockAddr::Unix(ref unix) => unix.fmt(f),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(ref nl) => nl.fmt(f),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(ref sc) => sc.fmt(f),
}
}
}
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
pub mod netlink {
use ::sys::socket::addr::{AddressFamily};
use libc::{sa_family_t, sockaddr_nl};
@@ -642,11 +809,10 @@ pub mod netlink {
}
}
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
pub mod sys_control {
- use ::sys::socket::consts;
use ::sys::socket::addr::{AddressFamily};
- use libc::{c_uchar, uint16_t, uint32_t};
+ use libc::{self, c_uchar, uint16_t, uint32_t};
use std::{fmt, mem};
use std::hash::{Hash, Hasher};
use std::os::unix::io::RawFd;
@@ -702,7 +868,7 @@ pub mod sys_control {
let addr = sockaddr_ctl {
sc_len: mem::size_of::<sockaddr_ctl>() as c_uchar,
sc_family: AddressFamily::System as c_uchar,
- ss_sysaddr: consts::AF_SYS_CONTROL as uint16_t,
+ ss_sysaddr: libc::AF_SYS_CONTROL as uint16_t,
sc_id: id,
sc_unit: unit,
sc_reserved: [0; 5]
diff --git a/src/sys/socket/consts.rs b/src/sys/socket/consts.rs
deleted file mode 100644
index ad9c522f..00000000
--- a/src/sys/socket/consts.rs
+++ /dev/null
@@ -1,437 +0,0 @@
-pub use self::os::*;
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod os {
- use libc::{self, c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
- pub const AF_NETLINK: c_int = libc::AF_NETLINK;
- pub const AF_PACKET: c_int = libc::AF_PACKET;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = 4;
-
- pub const SOL_IP: c_int = libc::SOL_IP;
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const SOL_TCP: c_int = libc::SOL_TCP;
- pub const SOL_UDP: c_int = 17;
- pub const SOL_IPV6: c_int = libc::SOL_IPV6;
- pub const SOL_NETLINK: c_int = libc::SOL_NETLINK;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = SOL_UDP;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BINDTODEVICE: c_int = libc::SO_BINDTODEVICE;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_BSDCOMPAT: c_int = libc::SO_BSDCOMPAT;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- pub const SO_DOMAIN: c_int = libc::SO_DOMAIN;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_MARK: c_int = libc::SO_MARK;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_PASSCRED: c_int = libc::SO_PASSCRED;
- pub const SO_PEEK_OFF: c_int = libc::SO_PEEK_OFF;
- pub const SO_PEERCRED: c_int = libc::SO_PEERCRED;
- pub const SO_PRIORITY: c_int = libc::SO_PRIORITY;
- pub const SO_PROTOCOL: c_int = libc::SO_PROTOCOL;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVBUFFORCE: c_int = 33;
- pub const SO_RCVLOWAT: c_int = libc::SO_RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_RXQ_OVFL: c_int = libc::SO_RXQ_OVFL;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_SNDBUFFORCE: c_int = libc::SO_SNDBUFFORCE;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
- pub const SO_BUSY_POLL: c_int = libc::SO_BUSY_POLL;
- #[cfg(target_os = "linux")]
- pub const SO_ORIGINAL_DST: c_int = 80;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = libc::TCP_MAXSEG;
- pub const TCP_CORK: c_int = libc::TCP_CORK;
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 32;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
-
- pub const IPV6_ADD_MEMBERSHIP: c_int = libc::IPV6_ADD_MEMBERSHIP;
- pub const IPV6_DROP_MEMBERSHIP: c_int = libc::IPV6_DROP_MEMBERSHIP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_CTRUNC,
- MSG_TRUNC,
- MSG_DONTWAIT,
- MSG_EOR,
- MSG_ERRQUEUE,
- MSG_CMSG_CLOEXEC,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-
- // Ancillary message types
- pub const SCM_RIGHTS: c_int = libc::SCM_RIGHTS;
-}
-
-// Not all of these constants exist on freebsd
-#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))]
-mod os {
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd"))]
- use libc::{self, c_int, uint8_t};
- #[cfg(any(target_os = "openbsd", target_os = "netbsd"))]
- use libc::{self, c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const AF_SYSTEM: c_int = libc::AF_SYSTEM;
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const AF_SYS_CONTROL: c_int = 2;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = libc::SOCK_RDM;
-
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = 17;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const SYSPROTO_CONTROL: c_int = 2;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_DONTTRUNC: c_int = 0x2000;
- pub const SO_USELOOPBACK: c_int = libc::SO_USELOOPBACK;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LABEL: c_int = 0x1010;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_NREAD: c_int = 0x1020;
- pub const SO_NKE: c_int = 0x1021;
- pub const SO_NOSIGPIPE: c_int = 0x1022;
- pub const SO_NOADDRERR: c_int = 0x1023;
- pub const SO_NOTIFYCONFLICT: c_int = 0x1026;
- pub const SO_NP_EXTENSIONS: c_int = 0x1083;
- pub const SO_NWRITE: c_int = 0x1024;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_PEERLABEL: c_int = 0x1011;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVLOWAT: c_int = libc::SO_RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_RANDOMPORT: c_int = 0x1082;
- pub const SO_RESTRICTIONS: c_int = 0x1081;
- pub const SO_RESTRICT_DENYIN: c_int = 0x00000001;
- pub const SO_RESTRICT_DENYOUT: c_int = 0x00000002;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_REUSESHAREUID: c_int = 0x1025;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_TIMESTAMP_MONOTONIC: c_int = 0x0800;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_WANTMORE: c_int = 0x4000;
- pub const SO_WANTOOBFLAG: c_int = 0x8000;
- #[allow(overflowing_literals)]
- pub const SO_RESTRICT_DENYSET: c_int = 0x80000000;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = 2;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const TCP_KEEPALIVE: c_int = libc::TCP_KEEPALIVE;
- #[cfg(target_os = "freebsd")]
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 9;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
-
- pub const IPV6_JOIN_GROUP: c_int = libc::IPV6_JOIN_GROUP;
- pub const IPV6_LEAVE_GROUP: c_int = libc::IPV6_LEAVE_GROUP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_EOR,
- MSG_TRUNC,
- MSG_CTRUNC,
- MSG_DONTWAIT,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-
- // Ancillary message types
- pub const SCM_RIGHTS: c_int = 1;
-}
-
-#[cfg(target_os = "dragonfly")]
-mod os {
- use libc::{c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = libc::SOCK_RDM;
-
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = libc::IPPROTO_UDP;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_NOSIGPIPE: c_int = libc::SO_NOSIGPIPE;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVLOWAT: c_int = libc::RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = libc::TCP_MAXSEG;
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 9;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
- pub const IPV6_JOIN_GROUP: c_int = libc::IPV6_JOIN_GROUP;
- pub const IPV6_LEAVE_GROUP: c_int = libc::IPV6_LEAVE_GROUP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_DONTWAIT,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use nixtest::{assert_const_eq,get_int_const,GetConst};
- use libc::{c_char};
- use std::fmt;
-
- impl fmt::Display for MsgFlags {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.bits())
- }
- }
-
- impl GetConst for MsgFlags {
- unsafe fn get_const(name: *const c_char) -> MsgFlags {
- MsgFlags::from_bits_truncate(get_int_const(name))
- }
- }
-
- macro_rules! check_const {
- ($($konst:ident),+) => {{
- $(assert_const_eq(stringify!($konst), $konst);)+
- }};
- }
-
- #[test]
- pub fn test_const_values() {
- check_const!(
- AF_UNIX,
- AF_LOCAL,
- AF_INET,
- AF_INET6,
- SOCK_STREAM,
- SOCK_DGRAM,
- SOCK_SEQPACKET,
- SOCK_RAW,
- SOCK_RDM,
- SOL_SOCKET,
- IPPROTO_IP,
- IPPROTO_IPV6,
- IPPROTO_TCP,
- IPPROTO_UDP,
- SO_ACCEPTCONN,
- SO_BROADCAST,
- SO_DEBUG,
- SO_ERROR,
- SO_DONTROUTE,
- SO_KEEPALIVE,
- SO_LINGER,
- SO_OOBINLINE,
- SO_RCVBUF,
- SO_RCVLOWAT,
- SO_SNDLOWAT,
- SO_RCVTIMEO,
- SO_SNDTIMEO,
- SO_REUSEADDR,
- // SO_REUSEPORT,
- SO_SNDBUF,
- SO_TIMESTAMP,
- SO_TYPE,
- TCP_NODELAY,
- TCP_MAXSEG,
- IP_MULTICAST_IF,
- IP_MULTICAST_TTL,
- IP_MULTICAST_LOOP,
- IP_ADD_MEMBERSHIP,
- IP_DROP_MEMBERSHIP,
- INADDR_ANY,
- INADDR_NONE,
- INADDR_BROADCAST,
- MSG_OOB,
- MSG_PEEK,
- MSG_DONTWAIT,
- MSG_EOR,
- MSG_TRUNC,
- MSG_CTRUNC,
- SHUT_RD,
- SHUT_WR,
- SHUT_RDWR
- );
-
-
- }
-
- #[cfg(target_os = "linux")]
- #[test]
- pub fn test_general_linux_consts() {
- // TODO Figure out how to test new constants
- check_const!(
- SOL_IP,
- SOL_TCP,
- SOL_UDP,
- SOL_IPV6,
- SO_BINDTODEVICE,
- SO_BSDCOMPAT,
- // SO_DOMAIN,
- // SO_MARK,
- TCP_CORK,
- // SO_BUSY_POLL,
- // SO_RXQ_OVFL,
- SO_PRIORITY,
- // SO_PROTOCOL,
- SO_RCVBUFFORCE,
- // SO_PEEK_OFF,
- MSG_ERRQUEUE);
- }
-
- #[cfg(all(target_os = "linux", not(target_arch="arm")))]
- #[test]
- pub fn test_linux_not_arm_consts() {
- // TODO Figure out how to test new constants
- check_const!(
- SO_PASSCRED,
- SO_PEERCRED,
- SO_SNDBUFFORCE);
- }
-
-}
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index c11b5367..86129fcf 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -5,13 +5,12 @@ use {Error, Errno, Result};
use features;
use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
-use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
+use libc::{self, c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
use std::{mem, ptr, slice};
use std::os::unix::io::RawFd;
use sys::uio::IoVec;
mod addr;
-mod consts;
mod ffi;
mod multicast;
pub mod sockopt;
@@ -48,28 +47,112 @@ pub use self::multicast::{
ip_mreq,
ipv6_mreq,
};
-pub use self::consts::*;
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)]
#[repr(i32)]
pub enum SockType {
- Stream = consts::SOCK_STREAM,
- Datagram = consts::SOCK_DGRAM,
- SeqPacket = consts::SOCK_SEQPACKET,
- Raw = consts::SOCK_RAW,
- Rdm = consts::SOCK_RDM,
+ /// Provides sequenced, reliable, two-way, connection-
+ /// based byte streams. An out-of-band data transmission
+ /// mechanism may be supported.
+ Stream = libc::SOCK_STREAM,
+ /// Supports datagrams (connectionless, unreliable
+ /// messages of a fixed maximum length).
+ Datagram = libc::SOCK_DGRAM,
+ /// Provides a sequenced, reliable, two-way connection-
+ /// based data transmission path for datagrams of fixed
+ /// maximum length; a consumer is required to read an
+ /// entire packet with each input system call.
+ SeqPacket = libc::SOCK_SEQPACKET,
+ /// Provides raw network protocol access.
+ Raw = libc::SOCK_RAW,
+ /// Provides a reliable datagram layer that does not
+ /// guarantee ordering.
+ Rdm = libc::SOCK_RDM,
+}
+
+/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
+/// to specify the protocol to use.
+#[repr(i32)]
+pub enum SockProtocol {
+ /// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Tcp = libc::IPPROTO_TCP,
+ /// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Udp = libc::IPPROTO_UDP,
+ /// Allows applications and other KEXTs to be notified when certain kernel events occur
+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ KextEvent = libc::SYSPROTO_EVENT,
+ /// Allows applications to configure and control a KEXT
+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ KextControl = libc::SYSPROTO_CONTROL,
}
-// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
bitflags!(
+ /// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
pub struct SockFlag: c_int {
const SOCK_NONBLOCK = 0o0004000;
const SOCK_CLOEXEC = 0o2000000;
}
);
+libc_bitflags!{
+ /// Flags for send/recv and their relatives
+ pub flags MsgFlags: libc::c_int {
+ /// Sends or requests out-of-band data on sockets that support this notion
+ /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also
+ /// support out-of-band data.
+ MSG_OOB,
+ /// Peeks at an incoming message. The data is treated as unread and the next
+ /// [`recv()`](fn.recv.html)
+ /// or similar function shall still return this data.
+ MSG_PEEK,
+ /// Enables nonblocking operation; if the operation would block,
+ /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar
+ /// behavior to setting the `O_NONBLOCK` flag
+ /// (via the [`fcntl`](../../fcntl/fn.fcntl.html)
+ /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per-
+ /// call option, whereas `O_NONBLOCK` is a setting on the open file
+ /// description (see [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)),
+ /// which will affect all threads in
+ /// the calling process and as well as other processes that hold
+ /// file descriptors referring to the same open file description.
+ MSG_DONTWAIT,
+ /// Receive flags: Control Data was discarded (buffer too small)
+ MSG_CTRUNC,
+ /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram
+ /// (since Linux 2.4.27/2.6.8),
+ /// netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4)
+ /// sockets: return the real length of the packet or datagram, even
+ /// when it was longer than the passed buffer. Not implemented for UNIX
+ /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets.
+ ///
+ /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp).
+ MSG_TRUNC,
+ /// Terminates a record (when this notion is supported, as for
+ /// sockets of type [`SeqPacket`](enum.SockType.html)).
+ MSG_EOR,
+ /// This flag specifies that queued errors should be received from
+ /// the socket error queue. (For more details, see
+ /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
+ #[cfg(any(target_os = "linux", target_os = "android"))]
+ MSG_ERRQUEUE,
+ /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
+ /// file descriptor using the `SCM_RIGHTS` operation (described in
+ /// [unix(7)](https://linux.die.net/man/7/unix)).
+ /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of
+ /// [open(2)](https://linux.die.net/man/2/open).
+ ///
+ /// Only used in [`recvmsg`](fn.recvmsg.html) function.
+ #[cfg(any(target_os = "linux", target_os = "android"))]
+ MSG_CMSG_CLOEXEC,
+ }
+}
+
/// 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
@@ -157,7 +240,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
self.0 = &buf[cmsg_align(cmsg_len)..];
match (cmsg.cmsg_level, cmsg.cmsg_type) {
- (SOL_SOCKET, SCM_RIGHTS) => unsafe {
+ (libc::SOL_SOCKET, libc::SCM_RIGHTS) => unsafe {
Some(ControlMessage::ScmRights(
slice::from_raw_parts(
&cmsg.cmsg_data as *const _ as *const _, 1)))
@@ -221,8 +304,8 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmRights(fds) => {
let cmsg = cmsghdr {
cmsg_len: self.len() as type_of_cmsg_len,
- cmsg_level: SOL_SOCKET,
- cmsg_type: SCM_RIGHTS,
+ cmsg_level: libc::SOL_SOCKET,
+ cmsg_type: libc::SCM_RIGHTS,
cmsg_data: [],
};
copy_bytes(&cmsg, buf);
@@ -330,9 +413,20 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
/// Create an endpoint for communication
///
+/// The `protocol` specifies a particular protocol to be used with the
+/// socket. Normally only a single protocol exists to support a
+/// particular socket type within a given protocol family, in which case
+/// protocol can be specified as `None`. However, it is possible that many
+/// protocols may exist, in which case a particular protocol must be
+/// specified in this manner.
+///
/// [Further reading](http://man7.org/linux/man-pages/man2/socket.2.html)
-pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_int) -> Result<RawFd> {
+pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
let mut ty = ty as c_int;
+ let protocol = match protocol.into() {
+ None => 0,
+ Some(p) => p as c_int,
+ };
let feat_atomic = features::socket_atomic_cloexec();
if feat_atomic {
@@ -358,9 +452,13 @@ pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_
/// Create a pair of connected sockets
///
/// [Further reading](http://man7.org/linux/man-pages/man2/socketpair.2.html)
-pub fn socketpair(domain: AddressFamily, ty: SockType, protocol: c_int,
+pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
flags: SockFlag) -> Result<(RawFd, RawFd)> {
let mut ty = ty as c_int;
+ let protocol = match protocol.into() {
+ None => 0,
+ Some(p) => p as c_int,
+ };
let feat_atomic = features::socket_atomic_cloexec();
if feat_atomic {
@@ -551,13 +649,13 @@ pub struct ucred {
/// [Further reading](http://man7.org/linux/man-pages/man2/setsockopt.2.html)
#[repr(i32)]
pub enum SockLevel {
- Socket = SOL_SOCKET,
- Tcp = IPPROTO_TCP,
- Ip = IPPROTO_IP,
- Ipv6 = IPPROTO_IPV6,
- Udp = IPPROTO_UDP,
+ 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"))]
- Netlink = SOL_NETLINK,
+ Netlink = libc::SOL_NETLINK,
}
/// Represents a socket option that can be accessed or set. Used as an argument
@@ -639,22 +737,22 @@ pub unsafe fn sockaddr_storage_to_addr(
}
match addr.ss_family as c_int {
- consts::AF_INET => {
+ libc::AF_INET => {
assert!(len as usize == mem::size_of::<sockaddr_in>());
let ret = *(addr as *const _ as *const sockaddr_in);
Ok(SockAddr::Inet(InetAddr::V4(ret)))
}
- consts::AF_INET6 => {
+ libc::AF_INET6 => {
assert!(len as usize == mem::size_of::<sockaddr_in6>());
Ok(SockAddr::Inet(InetAddr::V6((*(addr as *const _ as *const sockaddr_in6)))))
}
- consts::AF_UNIX => {
+ libc::AF_UNIX => {
let sun = *(addr as *const _ as *const sockaddr_un);
let pathlen = len - offset_of!(sockaddr_un, sun_path);
Ok(SockAddr::Unix(UnixAddr(sun, pathlen)))
}
#[cfg(any(target_os = "linux", target_os = "android"))]
- consts::AF_NETLINK => {
+ libc::AF_NETLINK => {
use libc::sockaddr_nl;
Ok(SockAddr::Netlink(NetlinkAddr(*(addr as *const _ as *const sockaddr_nl))))
}
@@ -681,9 +779,9 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
use libc::shutdown;
let how = match how {
- Shutdown::Read => consts::SHUT_RD,
- Shutdown::Write => consts::SHUT_WR,
- Shutdown::Both => consts::SHUT_RDWR,
+ Shutdown::Read => libc::SHUT_RD,
+ Shutdown::Write => libc::SHUT_WR,
+ Shutdown::Both => libc::SHUT_RDWR,
};
Errno::result(shutdown(df, how)).map(drop)
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 61d85ec3..3c13c539 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -1,9 +1,7 @@
-use super::{ffi, consts, GetSockOpt, SetSockOpt};
+use super::{ffi, GetSockOpt, SetSockOpt};
use {Errno, Result};
use sys::time::TimeVal;
-use libc::{c_int, uint8_t, c_void, socklen_t};
-#[cfg(target_os = "linux")]
-use libc::sockaddr_in;
+use libc::{self, c_int, uint8_t, c_void, socklen_t};
use std::mem;
use std::os::unix::io::RawFd;
@@ -130,52 +128,49 @@ macro_rules! sockopt_impl {
*
*/
-sockopt_impl!(Both, ReuseAddr, consts::SOL_SOCKET, consts::SO_REUSEADDR, bool);
-sockopt_impl!(Both, ReusePort, consts::SOL_SOCKET, consts::SO_REUSEPORT, bool);
-sockopt_impl!(Both, TcpNoDelay, consts::IPPROTO_TCP, consts::TCP_NODELAY, bool);
-sockopt_impl!(Both, Linger, consts::SOL_SOCKET, consts::SO_LINGER, super::linger);
-sockopt_impl!(SetOnly, IpAddMembership, consts::IPPROTO_IP, consts::IP_ADD_MEMBERSHIP, super::ip_mreq);
-sockopt_impl!(SetOnly, IpDropMembership, consts::IPPROTO_IP, consts::IP_DROP_MEMBERSHIP, super::ip_mreq);
+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, consts::IPPROTO_IPV6, consts::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq);
+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, consts::IPPROTO_IPV6, consts::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq);
+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, consts::IPPROTO_IPV6, consts::IPV6_JOIN_GROUP, super::ipv6_mreq);
+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, consts::IPPROTO_IPV6, consts::IPV6_LEAVE_GROUP, super::ipv6_mreq);
-sockopt_impl!(Both, IpMulticastTtl, consts::IPPROTO_IP, consts::IP_MULTICAST_TTL, u8);
-sockopt_impl!(Both, IpMulticastLoop, consts::IPPROTO_IP, consts::IP_MULTICAST_LOOP, bool);
-sockopt_impl!(Both, ReceiveTimeout, consts::SOL_SOCKET, consts::SO_RCVTIMEO, TimeVal);
-sockopt_impl!(Both, SendTimeout, consts::SOL_SOCKET, consts::SO_SNDTIMEO, TimeVal);
-sockopt_impl!(Both, Broadcast, consts::SOL_SOCKET, consts::SO_BROADCAST, bool);
-sockopt_impl!(Both, OobInline, consts::SOL_SOCKET, consts::SO_OOBINLINE, bool);
-sockopt_impl!(GetOnly, SocketError, consts::SOL_SOCKET, consts::SO_ERROR, i32);
-sockopt_impl!(Both, KeepAlive, consts::SOL_SOCKET, consts::SO_KEEPALIVE, bool);
+sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::ipv6_mreq);
+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);
+sockopt_impl!(Both, SendTimeout, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal);
+sockopt_impl!(Both, Broadcast, libc::SOL_SOCKET, libc::SO_BROADCAST, bool);
+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, consts::SOL_SOCKET, consts::SO_PEERCRED, super::ucred);
+sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::ucred);
#[cfg(any(target_os = "macos",
target_os = "ios"))]
-sockopt_impl!(Both, TcpKeepAlive, consts::IPPROTO_TCP, consts::TCP_KEEPALIVE, u32);
+sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly",
target_os = "linux",
target_os = "android",
target_os = "nacl"))]
-sockopt_impl!(Both, TcpKeepIdle, consts::IPPROTO_TCP, consts::TCP_KEEPIDLE, u32);
-sockopt_impl!(Both, RcvBuf, consts::SOL_SOCKET, consts::SO_RCVBUF, usize);
-sockopt_impl!(Both, SndBuf, consts::SOL_SOCKET, consts::SO_SNDBUF, usize);
-#[cfg(target_os = "linux")]
-sockopt_impl!(SetOnly, RcvBufForce, consts::SOL_SOCKET, consts::SO_RCVBUFFORCE, usize);
-#[cfg(all(target_os = "linux", not(target_arch="arm")))]
-sockopt_impl!(SetOnly, SndBufForce, consts::SOL_SOCKET, consts::SO_SNDBUFFORCE, usize);
-sockopt_impl!(GetOnly, SockType, consts::SOL_SOCKET, consts::SO_TYPE, super::SockType);
-#[cfg(any(target_os = "freebsd",
- target_os = "linux",
- target_os = "nacl"))]
-sockopt_impl!(GetOnly, AcceptConn, consts::SOL_SOCKET, consts::SO_ACCEPTCONN, bool);
-#[cfg(target_os = "linux")]
-sockopt_impl!(GetOnly, OriginalDst, consts::SOL_IP, consts::SO_ORIGINAL_DST, sockaddr_in);
+sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
+sockopt_impl!(Both, RcvBuf, libc::SOL_SOCKET, libc::SO_RCVBUF, usize);
+sockopt_impl!(Both, SndBuf, libc::SOL_SOCKET, libc::SO_SNDBUF, usize);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(SetOnly, RcvBufForce, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize);
+sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType);
+sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
/*
*
@@ -383,7 +378,7 @@ mod test {
fn can_get_peercred_on_unix_socket() {
use super::super::*;
- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
assert_eq!(a_cred, b_cred);
@@ -395,7 +390,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
let a_type = getsockopt(a, super::SockType).unwrap();
assert!(a_type == SockType::Stream);
close(a).unwrap();
@@ -407,7 +402,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), 0).unwrap();
+ let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
let s_type = getsockopt(s, super::SockType).unwrap();
assert!(s_type == SockType::Datagram);
close(s).unwrap();
@@ -421,7 +416,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), 0).unwrap();
+ let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
let s_listening = getsockopt(s, super::AcceptConn).unwrap();
assert!(!s_listening);
listen(s, 10).unwrap();