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, RawFd}; use ports::localhost; #[test] pub fn test_inetv4_addr_to_sock_addr() { let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); let addr = InetAddr::from_std(&actual); match addr { InetAddr::V4(addr) => { let ip: u32 = 0x7f000001; let port: u16 = 3000; assert_eq!(addr.sin_addr.s_addr, ip.to_be()); assert_eq!(addr.sin_port, port.to_be()); } _ => panic!("nope"), } assert_eq!(addr.to_str(), "127.0.0.1:3000"); let inet = addr.to_std(); assert_eq!(actual, inet); } #[test] pub fn test_path_to_sock_addr() { let actual = Path::new("/foo/bar"); let addr = UnixAddr::new(actual).unwrap(); let expect: &'static [i8] = unsafe { mem::transmute(&b"/foo/bar"[..]) }; assert_eq!(&addr.0.sun_path[..8], expect); assert_eq!(addr.path(), Some(actual)); } #[test] pub fn test_getsockname() { use std::net::TcpListener; let addr = localhost(); let sock = TcpListener::bind(&*addr).unwrap(); let res = getsockname(sock.as_raw_fd()).unwrap(); assert_eq!(addr, res.to_str()); } #[test] pub fn test_socketpair() { use nix::unistd::{read, write}; use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag}; let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()) .unwrap(); write(fd1, b"hello").unwrap(); let mut buf = [0;5]; read(fd2, &mut buf).unwrap(); 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 = 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(); }