Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ jobs:
- name: Check
run: cargo +${{ matrix.toolchain }} check --target ${{ matrix.target }}

check-mach2:
name: Check (mach2 ${{ matrix.mach2 }})
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
# The oldest and newest versions accepted by the `mach2` requirement
mach2: ["0.4.3", "0.7.0"]

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-ios

- name: Pin mach2
run: cargo update -p mach2 --precise ${{ matrix.mach2 }}

- name: Test
run: cargo test -- --test-threads=1

- name: Check iOS
run: cargo check --target aarch64-apple-ios --all-targets

check-hurd:
name: Check (x86_64-unknown-hurd-gnu)
runs-on: ubuntu-latest
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Changed

- Widened the `mach2` requirement from 0.4 to `>=0.4.2, <0.8` (macOS & iOS),
allowing dependents to share a single `mach2` version.
- Depend on `libc` & `mach2` without their default (`std`) features.

### Fixed

- Resolved Clippy `ptr_as_ptr` violations on FreeBSD, NetBSD & Windows.

## [4.0.0] - 2026-08-07

### Added
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ std = ["bitflags/std"]

[dependencies]
bitflags = { version = "2.6", default-features = false }
libc = "0.2.172"
libc = { version = "0.2.172", default-features = false }

[target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies]
mach2 = "0.4.2"
mach2 = { version = ">=0.4.2, <0.8", default-features = false }

[target.'cfg(windows)'.dependencies.windows-sys]
# Accept a range so dependents can unify on a single windows-sys version.
Expand Down
20 changes: 13 additions & 7 deletions src/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,18 +250,24 @@ mod tests {
let buffers = (0..8)
.map(|_| alloc(1, Protection::READ_WRITE))
.collect::<Result<alloc::vec::Vec<_>>>()?;
let start = alloc(1, Protection::READ_WRITE)?;
// Tests run concurrently, so another thread may map memory at the freed
// address before it is queried. Retry to rule out such a race.
let mut query = Ok(crate::Region::default());
for _ in 0..16 {
let start = alloc(1, Protection::READ_WRITE)?;
let base = start.as_ptr::<()>();
drop(start);

let base = start.as_ptr::<()>();
drop(start);
query = crate::query(base);
if matches!(query, Err(Error::UnmappedRegion)) {
return Ok(());
}
}

let query = crate::query(base);
assert!(
matches!(query, Err(Error::UnmappedRegion)),
panic!(
"expected unmapped region after free, got {query:?}; retained {} buffers",
buffers.len()
);
Ok(())
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ mod tests {
)
};
assert_eq!(address, page_address);
page_address = unsafe { (address as *mut u8).add(page::size()) }.cast();
page_address = unsafe { address.cast::<u8>().add(page::size()) }.cast();
}

AllocatedPages(allocation_base.cast(), total_size)
Expand Down
5 changes: 2 additions & 3 deletions src/os/freebsd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{Error, Protection, Region, Result};
use core::ffi::c_void;
use core::ptr;
use libc::{
KVME_PROT_EXEC, KVME_PROT_READ, KVME_PROT_WRITE, KVME_TYPE_DEFAULT, c_int, free, getpid,
Expand Down Expand Up @@ -46,7 +45,7 @@ impl Iterator for QueryIter {
// Since the struct size is given in the struct, it can be used future-proof
// (the definition is not required to be updated when new fields are added).
let offset = unsafe { self.vmmap_index * (*self.vmmap).kve_structsize as usize };
let entry = unsafe { &*((self.vmmap as *const c_void).add(offset) as *const kinfo_vmentry) };
let entry = unsafe { &*self.vmmap.cast::<u8>().add(offset).cast::<kinfo_vmentry>() };

self.vmmap_index += 1;
Some(Ok(Region {
Expand All @@ -61,7 +60,7 @@ impl Iterator for QueryIter {

impl Drop for QueryIter {
fn drop(&mut self) {
unsafe { free(self.vmmap as *mut c_void) }
unsafe { free(self.vmmap.cast()) }
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/os/netbsd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{Error, Protection, Region, Result};
use core::ffi::{c_char, c_int, c_void};
use core::ffi::{c_char, c_int};
use core::ptr;
use libc::{free, getpid, pid_t};

Expand Down Expand Up @@ -41,7 +41,7 @@ impl Iterator for QueryIter {
}

let offset = self.vmmap_index * core::mem::size_of::<kinfo_vmentry>();
let entry = unsafe { &*((self.vmmap as *const c_void).add(offset) as *const kinfo_vmentry) };
let entry = unsafe { &*self.vmmap.cast::<u8>().add(offset).cast::<kinfo_vmentry>() };

self.vmmap_index += 1;
Some(Ok(Region {
Expand All @@ -57,7 +57,7 @@ impl Iterator for QueryIter {

impl Drop for QueryIter {
fn drop(&mut self) {
unsafe { free(self.vmmap as *mut c_void) }
unsafe { free(self.vmmap.cast()) }
}
}

Expand Down
Loading