summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nix-test/src/lib.rs8
-rw-r--r--src/sys/socket/consts.rs66
-rw-r--r--src/sys/socket/mod.rs24
-rw-r--r--test/sys/test_socket.rs8
4 files changed, 68 insertions, 38 deletions
diff --git a/nix-test/src/lib.rs b/nix-test/src/lib.rs
index 25ab7fc7..cfe7b798 100644
--- a/nix-test/src/lib.rs
+++ b/nix-test/src/lib.rs
@@ -42,6 +42,8 @@ pub fn assert_size_of<T>(name: &str) {
}
}
+pub use ffi::get_int_const;
+
pub trait GetConst : PartialEq<Self> + fmt::Display {
unsafe fn get_const(name: *const c_char) -> Self;
}
@@ -51,3 +53,9 @@ impl GetConst for c_int {
ffi::get_int_const(name)
}
}
+
+impl GetConst for u32 {
+ unsafe fn get_const(name: *const c_char) -> u32 {
+ ffi::get_int_const(name) as u32
+ }
+}
diff --git a/src/sys/socket/consts.rs b/src/sys/socket/consts.rs
index eb1ca4b7..86b1aa04 100644
--- a/src/sys/socket/consts.rs
+++ b/src/sys/socket/consts.rs
@@ -85,15 +85,18 @@ mod os {
pub const INADDR_NONE: InAddrT = 0xffffffff;
pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
- pub type SockMessageFlags = c_int;
// Flags for send/recv and their relatives
- pub const MSG_OOB: SockMessageFlags = 0x1;
- pub const MSG_PEEK: SockMessageFlags = 0x2;
- pub const MSG_CTRUNC: SockMessageFlags = 0x08;
- pub const MSG_TRUNC: SockMessageFlags = 0x20;
- pub const MSG_DONTWAIT: SockMessageFlags = 0x40;
- pub const MSG_EOR: SockMessageFlags = 0x80;
- pub const MSG_ERRQUEUE: SockMessageFlags = 0x2000;
+ bitflags!{
+ flags MsgFlags : libc::c_int {
+ const MSG_OOB = 0x0001,
+ const MSG_PEEK = 0x0002,
+ const MSG_CTRUNC = 0x0008,
+ const MSG_TRUNC = 0x0020,
+ const MSG_DONTWAIT = 0x0040,
+ const MSG_EOR = 0x0080,
+ const MSG_ERRQUEUE = 0x2000,
+ }
+ }
// shutdown flags
pub const SHUT_RD: c_int = 0;
@@ -218,14 +221,17 @@ mod os {
pub const INADDR_NONE: InAddrT = 0xffffffff;
pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
- pub type SockMessageFlags = i32;
// Flags for send/recv and their relatives
- pub const MSG_OOB: SockMessageFlags = 0x1;
- pub const MSG_PEEK: SockMessageFlags = 0x2;
- pub const MSG_EOR: SockMessageFlags = 0x8;
- pub const MSG_TRUNC: SockMessageFlags = 0x10;
- pub const MSG_CTRUNC: SockMessageFlags = 0x20;
- pub const MSG_DONTWAIT: SockMessageFlags = 0x80;
+ bitflags!{
+ flags MsgFlags : libc::c_int {
+ const MSG_OOB = 0x01,
+ const MSG_PEEK = 0x02,
+ const MSG_EOR = 0x08,
+ const MSG_TRUNC = 0x10,
+ const MSG_CTRUNC = 0x20,
+ const MSG_DONTWAIT = 0x80,
+ }
+ }
// shutdown flags
pub const SHUT_RD: c_int = 0;
@@ -301,11 +307,14 @@ mod os {
pub const INADDR_NONE: InAddrT = 0xffffffff;
pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
- pub type SockMessageFlags = i32;
// Flags for send/recv and their relatives
- pub const MSG_OOB: SockMessageFlags = 0x1;
- pub const MSG_PEEK: SockMessageFlags = 0x2;
- pub const MSG_DONTWAIT: SockMessageFlags = 0x80;
+ bitflags!{
+ flags MsgFlags : libc::c_int {
+ const MSG_OOB = 0x01,
+ const MSG_PEEK = 0x02,
+ const MSG_DONTWAIT = 0x80,
+ }
+ }
// shutdown flags
pub const SHUT_RD: c_int = 0;
@@ -316,12 +325,25 @@ mod os {
#[cfg(test)]
mod test {
use super::*;
- use nixtest::assert_const_eq;
- use libc::c_int;
+ 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 as c_int);)+
+ $(assert_const_eq(stringify!($konst), $konst);)+
}};
}
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index bd87bbf1..c96a5c8d 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -123,7 +123,7 @@ pub struct RecvMsg<'a> {
pub bytes: usize,
cmsg_buffer: &'a [u8],
pub address: Option<SockAddr>,
- pub flags: SockMessageFlags,
+ pub flags: MsgFlags,
}
impl<'a> RecvMsg<'a> {
@@ -256,7 +256,7 @@ impl<'a> ControlMessage<'a> {
/// as with sendto.
///
/// Allocates if cmsgs is nonempty.
-pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'a>], flags: SockMessageFlags, addr: Option<&'a SockAddr>) -> Result<usize> {
+pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'a>], flags: MsgFlags, addr: Option<&'a SockAddr>) -> Result<usize> {
let mut len = 0;
let mut capacity = 0;
for cmsg in cmsgs {
@@ -293,7 +293,7 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
msg_controllen: len as size_t,
msg_flags: 0,
};
- let ret = unsafe { ffi::sendmsg(fd, &mhdr, flags) };
+ let ret = unsafe { ffi::sendmsg(fd, &mhdr, flags.bits()) };
Errno::result(ret).map(|r| r as usize)
}
@@ -301,7 +301,7 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
/// Receive message in scatter-gather vectors from a socket, and
/// optionally receive ancillary data into the provided buffer.
/// If no ancillary data is desired, use () as the type parameter.
-pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&'a mut CmsgSpace<T>>, flags: SockMessageFlags) -> Result<RecvMsg<'a>> {
+pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&'a mut CmsgSpace<T>>, flags: MsgFlags) -> Result<RecvMsg<'a>> {
let mut address: sockaddr_storage = unsafe { mem::uninitialized() };
let (msg_control, msg_controllen) = match cmsg_buffer {
Some(cmsg_buffer) => (cmsg_buffer as *mut _, mem::size_of_val(cmsg_buffer)),
@@ -316,7 +316,7 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
msg_controllen: msg_controllen as size_t,
msg_flags: 0,
};
- let ret = unsafe { ffi::recvmsg(fd, &mut mhdr, flags) };
+ let ret = unsafe { ffi::recvmsg(fd, &mut mhdr, flags.bits()) };
Ok(unsafe { RecvMsg {
bytes: try!(Errno::result(ret)) as usize,
@@ -324,7 +324,7 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
mhdr.msg_controllen as usize),
address: sockaddr_storage_to_addr(&address,
mhdr.msg_namelen as usize).ok(),
- flags: mhdr.msg_flags,
+ flags: MsgFlags::from_bits_truncate(mhdr.msg_flags),
} })
}
@@ -455,13 +455,13 @@ pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> {
/// bytes read
///
/// [Further reading](http://man7.org/linux/man-pages/man2/recv.2.html)
-pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: SockMessageFlags) -> Result<usize> {
+pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
unsafe {
let ret = ffi::recv(
sockfd,
buf.as_ptr() as *mut c_void,
buf.len() as size_t,
- flags);
+ flags.bits());
Errno::result(ret).map(|r| r as usize)
}
@@ -489,10 +489,10 @@ pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
}
}
-pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: SockMessageFlags) -> Result<usize> {
+pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result<usize> {
let ret = unsafe {
let (ptr, len) = addr.as_ffi_pair();
- ffi::sendto(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags, ptr, len)
+ ffi::sendto(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits(), ptr, len)
};
Errno::result(ret).map(|r| r as usize)
@@ -501,9 +501,9 @@ pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: SockMessageFlags) -
/// Send data to a connection-oriented socket. Returns the number of bytes read
///
/// [Further reading](http://man7.org/linux/man-pages/man2/send.2.html)
-pub fn send(fd: RawFd, buf: &[u8], flags: SockMessageFlags) -> Result<usize> {
+pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
let ret = unsafe {
- ffi::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags)
+ ffi::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits())
};
Errno::result(ret).map(|r| r as usize)
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index 258cde07..ea6ef71f 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -71,7 +71,7 @@ pub fn test_scm_rights() {
use nix::unistd::{pipe, read, write, close};
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
AddressFamily, SockType, SockFlag,
- ControlMessage, CmsgSpace,
+ ControlMessage, CmsgSpace, MsgFlags,
MSG_TRUNC, MSG_CTRUNC};
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
@@ -84,7 +84,7 @@ pub fn test_scm_rights() {
let iov = [IoVec::from_slice(b"hello")];
let fds = [r];
let cmsg = ControlMessage::ScmRights(&fds);
- assert_eq!(sendmsg(fd1, &iov, &[cmsg], 0, None).unwrap(), 5);
+ assert_eq!(sendmsg(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
close(r).unwrap();
close(fd1).unwrap();
}
@@ -93,7 +93,7 @@ pub fn test_scm_rights() {
let mut buf = [0u8; 5];
let iov = [IoVec::from_mut_slice(&mut buf[..])];
let mut cmsgspace: CmsgSpace<[RawFd; 1]> = CmsgSpace::new();
- let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), 0).unwrap();
+ let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
for cmsg in msg.cmsgs() {
if let ControlMessage::ScmRights(fd) = cmsg {
@@ -104,7 +104,7 @@ pub fn test_scm_rights() {
panic!("unexpected cmsg");
}
}
- assert_eq!(msg.flags & (MSG_TRUNC | MSG_CTRUNC), 0);
+ assert_eq!(msg.flags & (MSG_TRUNC | MSG_CTRUNC), MsgFlags::empty());
close(fd2).unwrap();
}