Skip to content

Instantly share code, notes, and snippets.

@matthewdowney
Created March 20, 2025 18:58
Show Gist options
  • Save matthewdowney/1114c0ae679a14e4f6b98911606953bf to your computer and use it in GitHub Desktop.
Save matthewdowney/1114c0ae679a14e4f6b98911606953bf to your computer and use it in GitHub Desktop.
mmap stdin in Rust, supports Mac OS (ARM) and Linux
// Conditional extern definitions for Linux/Android
#[cfg(any(target_os = "linux", target_os = "android"))]
#[link(name = "c")]
unsafe extern "C" {
fn mmap(addr: *mut u8, len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut u8;
fn __errno_location() -> *const i32;
fn lseek(fd: i32, offset: i64, whence: i32) -> i64;
fn open(path: *const u8, oflag: i32) -> i32;
}
// Conditional extern definitions for macOS/iOS
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[link(name = "c")]
unsafe extern "C" {
fn mmap(addr: *mut u8, len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut u8;
// macOS uses __error instead of __errno_location
fn __error() -> *mut i32;
fn lseek(fd: i32, offset: i64, whence: i32) -> i64;
fn open(path: *const u8, oflag: i32) -> i32;
}
/// Helper function to get errno in a platform-independent way.
#[inline]
unsafe fn get_errno() -> i32 {
#[cfg(any(target_os = "linux", target_os = "android"))]
{
unsafe { *__errno_location() }
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
{
unsafe { *__error() }
}
}
/// Define MAP_POPULATE conditionally:
#[cfg(any(target_os = "linux", target_os = "android"))]
const MAP_POPULATE: i32 = 0x08000;
#[cfg(any(target_os = "macos", target_os = "ios"))]
const MAP_POPULATE: i32 = 0; // MAP_POPULATE not supported on macOS
/// Map the file descriptor for standard input.
#[allow(dead_code)]
pub unsafe fn mmap_stdin<'a>() -> &'a [u8] {
unsafe { mmap_fd(0) }
}
/// Map the file at the given path.
#[allow(dead_code)]
pub unsafe fn mmap_path<'a>(path: &str) -> &'a [u8] {
let cpath = std::ffi::CString::new(path).expect("CString::new failed");
unsafe {
let fd = open(cpath.as_ptr() as *const u8, 0);
if fd == -1 {
panic!("open failed, errno {}", get_errno());
}
mmap_fd(fd)
}
}
/// Helper function that performs the mmap operation on a given file descriptor.
pub unsafe fn mmap_fd<'a>(fd: i32) -> &'a [u8] {
// SEEK_END is usually defined as 2
let seek_end = 2;
unsafe {
let size = lseek(fd, 0, seek_end);
if size == -1 {
panic!("lseek failed, errno {}", get_errno());
}
let prot_read = 0x01; // PROT_READ
let map_private = 0x02; // MAP_PRIVATE
let ptr = mmap(
std::ptr::null_mut(),
size as usize,
prot_read,
map_private | MAP_POPULATE,
fd,
0,
);
if ptr as isize == -1 {
panic!("mmap failed, errno {}", get_errno());
}
std::slice::from_raw_parts(ptr, size as usize)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn test_mmap_path_success() {
// Create a temporary file with known content.
let mut tmpfile = NamedTempFile::new().expect("Failed to create temp file");
let content = b"Hello, mmap!";
tmpfile
.write_all(content)
.expect("Failed to write to temp file");
// Flush and get the file path.
tmpfile.flush().expect("Failed to flush file");
let path = tmpfile.path().to_str().expect("Path is not valid UTF-8");
// Map the file using your function.
let mapped = unsafe { mmap_path(path) };
// Verify that the mapped content matches.
assert_eq!(mapped, content);
}
#[test]
#[should_panic(expected = "open failed")]
fn test_mmap_path_nonexistent() {
// Attempt to map a file that doesn't exist.
unsafe {
mmap_path("nonexistent_file.txt");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment