use std::io;
use std::os::raw::c_void;
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub(crate) fn open(name: &str, flags: i32) -> io::Result<i32> {
use libc::{shm_open, S_IRUSR, S_IWUSR};
let c_name = std::ffi::CString::new(name).map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidInput,
format!("shared memory name '{name}' contains a null byte"),
)
})?;
let fd = unsafe { shm_open(c_name.as_ptr(), flags, S_IRUSR | S_IWUSR) };
if fd == -1 {
let err = io::Error::last_os_error();
return Err(io::Error::new(err.kind(), format!("shm_open('{name}') failed: {err}")));
}
Ok(fd)
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
pub(crate) fn open(_name: &str, _flags: i32) -> io::Result<i32> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"POSIX shared memory is only supported on linux-x86_64",
))
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub(crate) fn map(
fd: i32,
size: usize,
prot: i32,
lock: bool,
name: &str,
) -> io::Result<*mut c_void> {
use libc::{mmap, MAP_FAILED, MAP_SHARED};
let mut flags = MAP_SHARED;
if lock {
flags |= libc::MAP_LOCKED;
}
let mapped = unsafe { mmap(std::ptr::null_mut(), size, prot, flags, fd, 0) };
if mapped == MAP_FAILED {
let err = io::Error::last_os_error();
return Err(io::Error::new(
err.kind(),
format!("mmap failed for '{name}': {err} ({size} bytes)"),
));
}
Ok(mapped)
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
pub(crate) fn map(
_fd: i32,
_size: usize,
_prot: i32,
_lock: bool,
_name: &str,
) -> io::Result<*mut c_void> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"POSIX shared memory is only supported on linux-x86_64",
))
}