Skip to content

Commit 242a6a0

Browse files
committed
Fix sendmsg on macOS when passing a zero entry cmsgs array.
1 parent b059ee4 commit 242a6a0

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4444
`MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)),
4545
`NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)), and
4646
`FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)).
47+
- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
48+
([#623](https://github.com/nix-rust/nix/pull/623))
4749

4850
## [0.8.1] 2017-04-16
4951

src/sys/socket/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,18 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
277277
None => (0 as *const _, 0),
278278
};
279279

280+
let cmsg_ptr = if capacity > 0 {
281+
cmsg_buffer.as_ptr() as *const c_void
282+
} else {
283+
ptr::null()
284+
};
285+
280286
let mhdr = msghdr {
281287
msg_name: name as *const c_void,
282288
msg_namelen: namelen,
283289
msg_iov: iov.as_ptr(),
284290
msg_iovlen: iov.len() as size_t,
285-
msg_control: cmsg_buffer.as_ptr() as *const c_void,
291+
msg_control: cmsg_ptr,
286292
msg_controllen: capacity as size_t,
287293
msg_flags: 0,
288294
};

test/sys/test_socket.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,39 @@ pub fn test_scm_rights() {
145145
close(w).unwrap();
146146
}
147147

148+
#[test]
149+
pub fn test_sendmsg_empty_cmsg() {
150+
use nix::sys::uio::IoVec;
151+
use nix::unistd::close;
152+
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
153+
AddressFamily, SockType, SockFlag,
154+
CmsgSpace, MsgFlags,
155+
MSG_TRUNC, MSG_CTRUNC};
156+
157+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
158+
SockFlag::empty())
159+
.unwrap();
160+
161+
{
162+
let iov = [IoVec::from_slice(b"hello")];
163+
assert_eq!(sendmsg(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), 5);
164+
close(fd1).unwrap();
165+
}
166+
167+
{
168+
let mut buf = [0u8; 5];
169+
let iov = [IoVec::from_mut_slice(&mut buf[..])];
170+
let mut cmsgspace: CmsgSpace<[RawFd; 1]> = CmsgSpace::new();
171+
let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
172+
173+
for _ in msg.cmsgs() {
174+
panic!("unexpected cmsg");
175+
}
176+
assert_eq!(msg.flags & (MSG_TRUNC | MSG_CTRUNC), MsgFlags::empty());
177+
close(fd2).unwrap();
178+
}
179+
}
180+
148181
// Test creating and using named unix domain sockets
149182
#[test]
150183
pub fn test_unixdomain() {

0 commit comments

Comments
 (0)