diff options
author | Alan Somers <asomers@gmail.com> | 2016-11-18 21:28:21 -0700 |
---|---|---|
committer | Alan Somers <asomers@gmail.com> | 2016-11-18 21:55:08 -0700 |
commit | 80a34a57313519272428f3f19f54b62261ee8001 (patch) | |
tree | e30d5dac2c38b6648b7828efe0f4d2266c3e57eb /test/sys/test_socket.rs | |
parent | 6d9d4fc25f70726c00e7eefd56b0cca10c8c61f5 (diff) | |
download | nix-80a34a57313519272428f3f19f54b62261ee8001.zip |
Fix Unix domain sockets.
There were multiple errors regarding Unix domain sockets:
* UnixAddr::path assumed that gethostbyname and similar functions would
include the terminating null as part of len. That is not universally
true. In fact, POSIX only guarantees that len will be at least large
enough to store the non-null-terminated path. So it could be larger or
smaller than nix was assuming. Since abstract sockets' paths are not
strings, we can't modify gethostbyname. Instead, I implemented the fix in
UnixAddr::path and UnixAddr::new. I clarified the documentation too.
* SockAddr::as_ffi_pair contained a Linuxism.
* sockaddr_storage_to_addr forgot to adjust sun_len when creating a UnixAddr
Diffstat (limited to 'test/sys/test_socket.rs')
-rw-r--r-- | test/sys/test_socket.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index bada1120..8b713c2b 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -140,3 +140,39 @@ pub fn test_scm_rights() { close(received_r).unwrap(); close(w).unwrap(); } + +// Test creating and using named unix domain sockets +#[test] +pub fn test_unixdomain() { + use nix::sys::socket::{AddressFamily, SockType, SockFlag}; + use nix::sys::socket::{bind, socket, connect, listen, accept, SockAddr}; + use nix::unistd::{read, write, close}; + use std::thread; + use tempdir::TempDir; + + let tempdir = TempDir::new("test_unixdomain").unwrap(); + let sockname = tempdir.path().join("sock"); + let s1 = socket(AddressFamily::Unix, SockType::Stream, + SockFlag::empty(), 0).expect("socket failed"); + let sockaddr = SockAddr::new_unix(&sockname).unwrap(); + bind(s1, &sockaddr).expect("bind failed"); + listen(s1, 10).expect("listen failed"); + + let thr = thread::spawn(move || { + let s2 = socket(AddressFamily::Unix, SockType::Stream, + SockFlag::empty(), 0).expect("socket failed"); + connect(s2, &sockaddr).expect("connect failed"); + write(s2, b"hello").expect("write failed"); + close(s2).unwrap(); + }); + + let s3 = accept(s1).expect("accept failed"); + + let mut buf = [0;5]; + read(s3, &mut buf).unwrap(); + close(s3).unwrap(); + close(s1).unwrap(); + thr.join().unwrap(); + + assert_eq!(&buf[..], b"hello"); +} |