use std::ffi;
use std::ptr;
pub type Error = crate::Error;
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) unsafe fn create_or_open(
create: bool,
path: String,
size: usize,
) -> Result<(*mut ffi::c_void,libc::c_int)> {
let path = ffi::CString::new(path.clone()).map_err(|_| Error::kErrorFFIFailed)?;
if create {
let ret = libc::shm_unlink(path.as_ptr());
if ret < 0 {
if *(libc::__error()) != libc::ENOENT {
return Err(Error::kErrorCreationFailed);
}
}
}
let flags = if create {
libc::O_CREAT | libc::O_RDWR
} else {
libc::O_RDONLY
};
let fd = libc::shm_open(path.as_ptr() as _, flags, 0755);
if fd < 0 {
if create {
return Err(Error::kErrorCreationFailed);
} else {
return Err(Error::kErrorOpeningFailed);
}
}
if create {
let ret = libc::ftruncate(fd, size as _);
if ret != 0 {
return Err(Error::kErrorCreationFailed);
}
}
let prot = if create {
libc::PROT_READ | libc::PROT_WRITE
} else {
libc::PROT_READ
};
let memory = libc::mmap(ptr::null_mut(), size as _, prot, libc::MAP_SHARED, fd, 0);
if memory == libc::MAP_FAILED {
return Err(Error::kErrorMappingFailed);
};
Ok((memory,fd))
}
pub(crate) unsafe fn unmap(data: *mut ffi::c_void, fd: libc::c_int,size:usize,path:String) {
libc::munmap(data, size);
libc::close(fd);
if let Err(_) = ffi::CString::new(path.clone()).map(|path| libc::shm_unlink(path.as_ptr())){}
}