vmap 0.6.3

Cross-platform library for fast and safe memory-mapped IO and boundary-free ring buffer.
Documentation
use std::os::raw::c_int;

use crate::{Error, Operation, Result};

#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn memfd_open() -> Result<c_int> {
    use std::os::raw::c_char;
    const NAME: &[u8] = b"vmap\0";
    let fd = unsafe {
        libc::syscall(
            libc::SYS_memfd_create,
            NAME.as_ptr() as *const c_char,
            libc::MFD_CLOEXEC,
        )
    };
    if fd < 0 {
        Err(Error::last_os_error(Operation::MemoryFd))
    } else {
        Ok(fd as c_int)
    }
}

#[cfg(target_os = "freebsd")]
pub fn memfd_open() -> Result<c_int> {
    let fd = unsafe { libc::shm_open(libc::SHM_ANON, libc::O_RDWR, 0o600) };
    if fd < 0 {
        Err(Error::last_os_error(Operation::MemoryFd))
    } else {
        Ok(fd as c_int)
    }
}

#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd")))]
pub fn memfd_open() -> Result<c_int> {
    const OFLAGS: c_int = libc::O_RDWR | libc::O_CREAT | libc::O_EXCL | libc::O_CLOEXEC;
    let mut path_bytes: [u8; 14] = *b"/vmap-XXXXXXX\0";

    loop {
        let path = {
            use std::io::Write;
            let pseudorandom = std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap()
                .subsec_nanos()
                % 10000000;
            write!(&mut path_bytes[6..], "{:0>7}", pseudorandom).unwrap();
            std::ffi::CStr::from_bytes_with_nul(&path_bytes).unwrap()
        };

        let fd = unsafe { libc::shm_open(path.as_ptr(), OFLAGS, 0o600) };
        if fd < 0 {
            let err = Error::last_os_error(Operation::MemoryFd);
            if err.raw_os_error() != Some(libc::EEXIST) {
                return Err(err);
            }
        } else {
            unsafe { libc::shm_unlink(path.as_ptr()) };
            return Ok(fd);
        }
    }
}