summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--src/sys/mman.rs9
-rw-r--r--src/sys/socket/addr.rs122
-rw-r--r--test/sys/test_mman.rs13
4 files changed, 143 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b2ae4b16..1a5efc2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased] - ReleaseDate
### Added
-- Add `MntFlags` and `unmount` on all of the BSDs.
+- Added `SockaddrStorage::{as_unix_addr, as_unix_addr_mut}`
+ ([#1871](https://github.com/nix-rust/nix/pull/1871))
+- Added `MntFlags` and `unmount` on all of the BSDs.
([#1849](https://github.com/nix-rust/nix/pull/1849))
- Added a 'Statfs::flags' method.
([#1849](https://github.com/nix-rust/nix/pull/1849))
@@ -41,9 +43,13 @@ This project adheres to [Semantic Versioning](https://semver.org/).
([#1792](https://github.com/nix-rust/nix/pull/1792))
- The `addr` argument of `sys::mman::mmap` is now of type `Option<NonZeroUsize>`.
([#1870](https://github.com/nix-rust/nix/pull/1870))
+- The `length` argument of `sys::mman::mmap` is now of type `NonZeroUsize`.
+ ([#1873](https://github.com/nix-rust/nix/pull/1873))
### Fixed
+- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux.
+ ([#1871](https://github.com/nix-rust/nix/pull/1871))
- Fix microsecond calculation for `TimeSpec`.
([#1801](https://github.com/nix-rust/nix/pull/1801))
- Fix `User::from_name` and `Group::from_name` panicking
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index dab8f445..2bee0916 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -418,7 +418,7 @@ pub fn munlockall() -> Result<()> {
/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
pub unsafe fn mmap(
addr: Option<NonZeroUsize>,
- length: size_t,
+ length: NonZeroUsize,
prot: ProtFlags,
flags: MapFlags,
fd: RawFd,
@@ -428,8 +428,8 @@ pub unsafe fn mmap(
std::ptr::null_mut(),
|a| usize::from(a) as *mut c_void
);
-
- let ret = libc::mmap(ptr, length, prot.bits(), flags.bits(), fd, offset);
+
+ let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
if ret == libc::MAP_FAILED {
Err(Errno::last())
@@ -520,8 +520,9 @@ pub unsafe fn madvise(
/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
/// # use std::ptr;
/// const ONE_K: size_t = 1024;
+/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap();
/// let mut slice: &mut [u8] = unsafe {
-/// let mem = mmap(None, ONE_K, ProtFlags::PROT_NONE,
+/// let mem = mmap(None, one_k_non_zero, ProtFlags::PROT_NONE,
/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index 34138efc..2b3e4919 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -1558,6 +1558,17 @@ impl SockaddrLike for SockaddrStorage {
let mut ss: libc::sockaddr_storage = mem::zeroed();
let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8;
ptr::copy(addr as *const u8, ssp, len as usize);
+ #[cfg(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux"
+ ))]
+ if i32::from(ss.ss_family) == libc::AF_UNIX {
+ // Safe because we UnixAddr is strictly smaller than
+ // SockaddrStorage, and we just initialized the structure.
+ (*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8;
+ }
Some(Self { ss })
}
} else {
@@ -1619,6 +1630,21 @@ impl SockaddrLike for SockaddrStorage {
}
}
}
+
+ #[cfg(any(
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux"
+ ))]
+ fn len(&self) -> libc::socklen_t {
+ match self.as_unix_addr() {
+ // The UnixAddr type knows its own length
+ Some(ua) => ua.len(),
+ // For all else, we're just a boring SockaddrStorage
+ None => mem::size_of_val(self) as libc::socklen_t
+ }
+ }
}
macro_rules! accessors {
@@ -1656,6 +1682,64 @@ macro_rules! accessors {
}
impl SockaddrStorage {
+ /// Downcast to an immutable `[UnixAddr]` reference.
+ pub fn as_unix_addr(&self) -> Option<&UnixAddr> {
+ cfg_if! {
+ if #[cfg(any(target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux"
+ ))]
+ {
+ let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
+ // Safe because UnixAddr is strictly smaller than
+ // sockaddr_storage, and we're fully initialized
+ let len = unsafe {
+ (*(p as *const UnixAddr )).sun_len as usize
+ };
+ } else {
+ let len = self.len() as usize;
+ }
+ }
+ // Sanity checks
+ if self.family() != Some(AddressFamily::Unix) ||
+ len < offset_of!(libc::sockaddr_un, sun_path) ||
+ len > mem::size_of::<libc::sockaddr_un>() {
+ None
+ } else {
+ Some(unsafe{&self.su})
+ }
+ }
+
+ /// Downcast to a mutable `[UnixAddr]` reference.
+ pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> {
+ cfg_if! {
+ if #[cfg(any(target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux"
+ ))]
+ {
+ let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
+ // Safe because UnixAddr is strictly smaller than
+ // sockaddr_storage, and we're fully initialized
+ let len = unsafe {
+ (*(p as *const UnixAddr )).sun_len as usize
+ };
+ } else {
+ let len = self.len() as usize;
+ }
+ }
+ // Sanity checks
+ if self.family() != Some(AddressFamily::Unix) ||
+ len < offset_of!(libc::sockaddr_un, sun_path) ||
+ len > mem::size_of::<libc::sockaddr_un>() {
+ None
+ } else {
+ Some(unsafe{&mut self.su})
+ }
+ }
+
#[cfg(any(target_os = "android", target_os = "linux"))]
accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr,
AddressFamily::Alg, libc::sockaddr_alg, alg}
@@ -3085,6 +3169,44 @@ mod tests {
}
}
+ mod sockaddr_storage {
+ use super::*;
+
+ #[test]
+ fn from_sockaddr_un_named() {
+ let ua = UnixAddr::new("/var/run/mysock").unwrap();
+ let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ss = unsafe {
+ SockaddrStorage::from_raw(ptr, Some(ua.len()))
+ }.unwrap();
+ assert_eq!(ss.len(), ua.len());
+ }
+
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[test]
+ fn from_sockaddr_un_abstract_named() {
+ let name = String::from("nix\0abstract\0test");
+ let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap();
+ let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ss = unsafe {
+ SockaddrStorage::from_raw(ptr, Some(ua.len()))
+ }.unwrap();
+ assert_eq!(ss.len(), ua.len());
+ }
+
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ #[test]
+ fn from_sockaddr_un_abstract_unnamed() {
+ let empty = String::new();
+ let ua = UnixAddr::new_abstract(empty.as_bytes()).unwrap();
+ let ptr = ua.as_ptr() as *const libc::sockaddr;
+ let ss = unsafe {
+ SockaddrStorage::from_raw(ptr, Some(ua.len()))
+ }.unwrap();
+ assert_eq!(ss.len(), ua.len());
+ }
+ }
+
mod unixaddr {
use super::*;
diff --git a/test/sys/test_mman.rs b/test/sys/test_mman.rs
index a43991c2..e748427b 100644
--- a/test/sys/test_mman.rs
+++ b/test/sys/test_mman.rs
@@ -1,11 +1,12 @@
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
+use std::num::NonZeroUsize;
#[test]
fn test_mmap_anonymous() {
unsafe {
let ptr = mmap(
None,
- 1,
+ NonZeroUsize::new(1).unwrap(),
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
-1,
@@ -25,10 +26,12 @@ fn test_mremap_grow() {
use nix::sys::mman::{mremap, MRemapFlags};
const ONE_K: size_t = 1024;
+ let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
+
let slice: &mut [u8] = unsafe {
let mem = mmap(
None,
- ONE_K,
+ one_k_non_zero,
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
-1,
@@ -79,12 +82,14 @@ fn test_mremap_grow() {
fn test_mremap_shrink() {
use nix::libc::{c_void, size_t};
use nix::sys::mman::{mremap, MRemapFlags};
+ use std::num::NonZeroUsize;
const ONE_K: size_t = 1024;
+ let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
let slice: &mut [u8] = unsafe {
let mem = mmap(
None,
- 10 * ONE_K,
+ ten_one_k,
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
-1,
@@ -100,7 +105,7 @@ fn test_mremap_shrink() {
let slice: &mut [u8] = unsafe {
let mem = mremap(
slice.as_mut_ptr() as *mut c_void,
- 10 * ONE_K,
+ ten_one_k.into(),
ONE_K,
MRemapFlags::empty(),
None,