mumblelink_reader 0.3.5

Mumblelink reader for Windows & Unix based operating systems
Documentation
use crate::mumble_link::{MumbleLinkReader, MumbleLinkData, CMumbleLinkData};
use crate::error::MumbleLinkHandlerError;
use std::io;
use core::ptr;
use std::ffi::CString;
use std::os::raw::c_uint;

#[cfg(all(unix))]
pub struct MumbleLinkHandler {
    fd: libc::c_int,
    pub ptr: *mut libc::c_void,
}

#[cfg(all(unix))]
impl MumbleLinkHandler {
    pub fn new() -> std::result::Result<MumbleLinkHandler, MumbleLinkHandlerError> {
        let uid = unsafe { libc::getuid() };
        let MUMBLE_LINK_STRUCT_SIZE: i64 = std::mem::size_of::<CMumbleLinkData>() as i64;
        let MMAP_PATH: CString = CString::new(format!("/MumbleLink.{}", uid)).expect("Failed to create MMAP_PATH");
        unsafe {
            let mut fd = libc::shm_open(
                MMAP_PATH.as_ptr(),
                libc::O_RDWR,
                libc::S_IRUSR as c_uint | libc::S_IWUSR as c_uint,
            );
            if fd < 0 {
                fd = libc::shm_open(
                    MMAP_PATH.as_ptr(),
                    libc::O_CREAT,
                    libc::S_IRUSR as c_uint | libc::S_IWUSR as c_uint,
                );
                let trunc: i32 = unsafe{libc::ftruncate(fd, MUMBLE_LINK_STRUCT_SIZE)};
                if trunc < 0 || fd < 0 {
                    return Err(MumbleLinkHandlerError::OSError(io::Error::last_os_error()));
                }
            }
            let ptr = libc::mmap(
                ptr::null_mut(),
                std::mem::size_of::<MumbleLinkData>(),
                libc::PROT_READ | libc::PROT_WRITE,
                libc::MAP_SHARED,
                fd,
                0,
            );
            if ptr as isize == -1 {
                libc::close(fd);
                return Err(MumbleLinkHandlerError::OSError(io::Error::last_os_error()));
            }
            Ok(MumbleLinkHandler {
                fd: fd,
                ptr: ptr,
            })
        }
    }
}

#[cfg(all(unix))]
impl Drop for MumbleLinkHandler {
    fn drop(&mut self) {
        unsafe {
            libc::close(self.fd);
            self.ptr = ptr::null_mut()
        }
    }
}