rsys 0.5.5

Crate for system and hardware information parsing
Documentation
use crate::{Error, Result};
use libc::{fileno, fopen, ioctl, size_t};
use std::ffi::{CStr, CString};

const _IOC_NRBITS: u64 = 8;
const _IOC_TYPEBITS: u64 = 8;
const _IOC_SIZEBITS: u64 = 14;
const _IOC_DIRBITS: u64 = 2;

const _IOC_NRMASK: u64 = (1 << _IOC_NRBITS) - 1;
const _IOC_TYPEMASK: u64 = (1 << _IOC_TYPEBITS) - 1;
const _IOC_SIZEMASK: u64 = (1 << _IOC_SIZEBITS) - 1;
const _IOC_DIRMASK: u64 = (1 << _IOC_DIRBITS) - 1;

const _IOC_NRSHIFT: u64 = 0;
const _IOC_TYPESHIFT: u64 = _IOC_NRSHIFT + _IOC_NRBITS;
const _IOC_SIZESHIFT: u64 = _IOC_TYPESHIFT + _IOC_TYPEBITS;
const _IOC_DIRSHIFT: u64 = _IOC_SIZESHIFT + _IOC_SIZEBITS;

const _IOC_NONE: u64 = 0;
const _IOC_WRITE: u64 = 1;
const _IOC_READ: u64 = 2;

#[allow(non_snake_case)]
const fn _IOC<T: Sized>(dir: u64, ty: u64, nr: u64) -> u64 {
    ((dir) << _IOC_DIRSHIFT)
        | ((ty) << _IOC_TYPESHIFT)
        | ((nr) << _IOC_NRSHIFT)
        | (std::mem::size_of::<T>() << _IOC_SIZESHIFT) as u64
}

#[allow(non_snake_case)]
const fn _IOR<T: Sized>(ty: u64, nr: u64) -> u64 {
    _IOC::<T>(_IOC_READ, ty, nr)
}

const BLKBSZGET: u64 = _IOR::<size_t>(0x12, 112);

pub(crate) fn blk_bsz_get(path: &str) -> Result<i64> {
    let mut size: usize = 0;
    let path = CString::new(path).map_err(|e| Error::InvalidInputError(path.to_string(), e.to_string()))?;
    let mode = CStr::from_bytes_with_nul(b"r\0").unwrap();

    let f = unsafe { fopen(path.as_ptr(), mode.as_ptr()) };
    if f.is_null() {
        return Err(Error::FileReadError(
            path.to_string_lossy().to_string(),
            "failed to get file descriptor from `fopen`".to_string(),
        ));
    }

    unsafe { ioctl(fileno(f), BLKBSZGET, &mut size) };

    Ok(size as i64)
}