summaryrefslogtreecommitdiff
path: root/test/sys
diff options
context:
space:
mode:
Diffstat (limited to 'test/sys')
-rw-r--r--test/sys/test_socket.rs55
1 files changed, 54 insertions, 1 deletions
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index e8cb4bed..7b95767e 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -2,7 +2,7 @@ use nix::sys::socket::{InetAddr, UnixAddr, getsockname};
use std::{mem, net};
use std::path::Path;
use std::str::FromStr;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsRawFd, RawFd};
use ports::localhost;
#[test]
@@ -63,3 +63,56 @@ pub fn test_socketpair() {
assert_eq!(&buf[..], b"hello");
}
+
+#[test]
+pub fn test_scm_rights() {
+ use nix::sys::uio::IoVec;
+ use nix::unistd::{pipe, read, write, close};
+ use nix::sys::socket::{socketpair, sendmsg, recvmsg,
+ AddressFamily, SockType, SockFlag,
+ ControlMessage, CmsgSpace,
+ MSG_TRUNC, MSG_CTRUNC};
+
+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
+ SockFlag::empty())
+ .unwrap();
+ let (r, w) = pipe().unwrap();
+ let mut received_r: Option<RawFd> = None;
+
+ {
+ 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);
+ close(r).unwrap();
+ close(fd1).unwrap();
+ }
+
+ {
+ 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();
+
+ for cmsg in msg.cmsgs() {
+ if let ControlMessage::ScmRights(fd) = cmsg {
+ assert_eq!(received_r, None);
+ assert_eq!(fd.len(), 1);
+ received_r = Some(fd[0]);
+ } else {
+ panic!("unexpected cmsg");
+ }
+ }
+ assert_eq!(msg.flags & (MSG_TRUNC | MSG_CTRUNC), 0);
+ close(fd2).unwrap();
+ }
+
+ let received_r = received_r.expect("Did not receive passed fd");
+ // Ensure that the received file descriptor works
+ write(w, b"world").unwrap();
+ let mut buf = [0u8; 5];
+ read(received_r, &mut buf).unwrap();
+ assert_eq!(&buf[..], b"world");
+ close(received_r).unwrap();
+ close(w).unwrap();
+}