Skip to content

Commit

Permalink
Fix sendmsg on macOS when passing a zero entry cmsgs array.
Browse files Browse the repository at this point in the history
  • Loading branch information
kinetiknz committed Jun 29, 2017
1 parent b059ee4 commit 242a6a0
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
`MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)),
`NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)), and
`FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)).
- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
([#623](https://github.com/nix-rust/nix/pull/623))

## [0.8.1] 2017-04-16

Expand Down
8 changes: 7 additions & 1 deletion src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,18 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
None => (0 as *const _, 0),
};

let cmsg_ptr = if capacity > 0 {
cmsg_buffer.as_ptr() as *const c_void
} else {
ptr::null()
};

let mhdr = msghdr {
msg_name: name as *const c_void,
msg_namelen: namelen,
msg_iov: iov.as_ptr(),
msg_iovlen: iov.len() as size_t,
msg_control: cmsg_buffer.as_ptr() as *const c_void,
msg_control: cmsg_ptr,
msg_controllen: capacity as size_t,
msg_flags: 0,
};
Expand Down
33 changes: 33 additions & 0 deletions test/sys/test_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,39 @@ pub fn test_scm_rights() {
close(w).unwrap();
}

#[test]
pub fn test_sendmsg_empty_cmsg() {
use nix::sys::uio::IoVec;
use nix::unistd::close;
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
AddressFamily, SockType, SockFlag,
CmsgSpace, MsgFlags,
MSG_TRUNC, MSG_CTRUNC};

let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
SockFlag::empty())
.unwrap();

{
let iov = [IoVec::from_slice(b"hello")];
assert_eq!(sendmsg(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), 5);
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), MsgFlags::empty()).unwrap();

for _ in msg.cmsgs() {
panic!("unexpected cmsg");
}
assert_eq!(msg.flags & (MSG_TRUNC | MSG_CTRUNC), MsgFlags::empty());
close(fd2).unwrap();
}
}

// Test creating and using named unix domain sockets
#[test]
pub fn test_unixdomain() {
Expand Down

0 comments on commit 242a6a0

Please sign in to comment.