2023-07-04 00:51:47 -04:00
|
|
|
use {
|
|
|
|
crate::Error,
|
|
|
|
std::io::{Read, Write},
|
|
|
|
};
|
|
|
|
|
2023-07-04 20:13:38 -04:00
|
|
|
/// Represents the major and minor numbers of a Unix special Device node
|
2023-07-04 00:51:47 -04:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Special {
|
|
|
|
pub major: u32,
|
|
|
|
pub minor: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Special {
|
2023-07-05 13:35:37 -04:00
|
|
|
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
2023-07-04 00:51:47 -04:00
|
|
|
let mut buf = [0; 8];
|
|
|
|
reader.read_exact(&mut buf)?;
|
|
|
|
let major: [u8; 4] = buf[..4].try_into()?;
|
|
|
|
let major = u32::from_le_bytes(major);
|
|
|
|
let minor: [u8; 4] = buf[4..].try_into()?;
|
|
|
|
let minor = u32::from_le_bytes(minor);
|
|
|
|
Ok(Self { major, minor })
|
|
|
|
}
|
|
|
|
|
2023-07-05 13:35:37 -04:00
|
|
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
2023-07-04 00:51:47 -04:00
|
|
|
writer.write_all(&self.major.to_le_bytes())?;
|
|
|
|
writer.write_all(&self.minor.to_le_bytes())?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-07-05 13:07:46 -04:00
|
|
|
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
|
|
|
pub(super) fn from_rdev(rdev: u64) -> Self {
|
2023-07-04 00:51:47 -04:00
|
|
|
Self {
|
2023-07-05 13:07:46 -04:00
|
|
|
major: ((rdev >> 8) & 0xff) as u32,
|
|
|
|
minor: (rdev & 0xffff00ff) as u32,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
pub(super) fn from_rdev(rdev: u64) -> Self {
|
|
|
|
let mut major = 0;
|
|
|
|
major |= (rdev & 0x00000000000fff00) >> 8;
|
|
|
|
major |= (rdev & 0xfffff00000000000) >> 32;
|
|
|
|
let mut minor = 0;
|
|
|
|
minor |= (rdev & 0x00000000000000ff) >> 0;
|
|
|
|
minor |= (rdev & 0x00000ffffff00000) >> 12;
|
|
|
|
Self {
|
|
|
|
major: major as u32,
|
|
|
|
minor: minor as u32,
|
2023-07-04 00:51:47 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-07-16 01:15:15 -04:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use std::fs::File;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn load_store() {
|
|
|
|
{
|
|
|
|
let mut fd = File::options()
|
|
|
|
.write(true)
|
|
|
|
.create(true)
|
|
|
|
.truncate(true)
|
|
|
|
.open("test/device")
|
|
|
|
.unwrap();
|
|
|
|
let dev = Special {
|
|
|
|
major: 42,
|
|
|
|
minor: 69,
|
|
|
|
};
|
|
|
|
dev.write(&mut fd).unwrap();
|
|
|
|
}
|
|
|
|
let mut fd = File::open("test/device").unwrap();
|
|
|
|
let dev = Special::read(&mut fd).unwrap();
|
|
|
|
assert_eq!(dev.major, 42);
|
|
|
|
assert_eq!(dev.minor, 69);
|
|
|
|
}
|
|
|
|
}
|