acyclic_fs/
native_identity.rs1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub struct NativeRootIdentity {
6 pub(crate) device: u64,
7 pub(crate) object: u64,
8}
9
10impl NativeRootIdentity {
11 pub fn from_file(file: &std::fs::File) -> std::io::Result<Self> {
18 native_root_identity(file)
19 }
20
21 pub(crate) fn from_metadata(metadata: &cap_std::fs::Metadata) -> std::io::Result<Self> {
22 native_metadata_identity(metadata)
23 }
24
25 #[must_use]
27 pub fn to_bytes(self) -> [u8; 16] {
28 let mut bytes = [0_u8; 16];
29 bytes[..8].copy_from_slice(&self.device.to_le_bytes());
30 bytes[8..].copy_from_slice(&self.object.to_le_bytes());
31 bytes
32 }
33
34 #[must_use]
36 pub fn from_bytes(bytes: [u8; 16]) -> Self {
37 let mut device = [0_u8; 8];
38 device.copy_from_slice(&bytes[..8]);
39 let mut object = [0_u8; 8];
40 object.copy_from_slice(&bytes[8..]);
41 Self {
42 device: u64::from_le_bytes(device),
43 object: u64::from_le_bytes(object),
44 }
45 }
46}
47
48#[cfg(unix)]
49fn native_metadata_identity(
50 metadata: &cap_std::fs::Metadata,
51) -> std::io::Result<NativeRootIdentity> {
52 use cap_std::fs::MetadataExt;
53 Ok(NativeRootIdentity {
54 device: metadata.dev(),
55 object: metadata.ino(),
56 })
57}
58
59#[cfg(windows)]
60fn native_metadata_identity(
61 metadata: &cap_std::fs::Metadata,
62) -> std::io::Result<NativeRootIdentity> {
63 use cap_primitives::fs::_WindowsByHandle;
64 let device = metadata.volume_serial_number().ok_or_else(|| {
65 std::io::Error::new(
66 std::io::ErrorKind::Unsupported,
67 "host volume identity is unavailable",
68 )
69 })?;
70 let object = metadata.file_index().ok_or_else(|| {
71 std::io::Error::new(
72 std::io::ErrorKind::Unsupported,
73 "host file identity is unavailable",
74 )
75 })?;
76 Ok(NativeRootIdentity {
77 device: u64::from(device),
78 object,
79 })
80}
81
82#[cfg(not(any(unix, windows)))]
83fn native_metadata_identity(_: &cap_std::fs::Metadata) -> std::io::Result<NativeRootIdentity> {
84 Err(std::io::Error::new(
85 std::io::ErrorKind::Unsupported,
86 "stable host file identity is unavailable on this platform",
87 ))
88}
89
90#[cfg(unix)]
91fn native_root_identity(file: &std::fs::File) -> std::io::Result<NativeRootIdentity> {
92 use std::os::unix::fs::MetadataExt;
93 let metadata = file.metadata()?;
94 Ok(NativeRootIdentity {
95 device: metadata.dev(),
96 object: metadata.ino(),
97 })
98}
99
100#[cfg(windows)]
101fn native_root_identity(file: &std::fs::File) -> std::io::Result<NativeRootIdentity> {
102 let metadata = cap_std::fs::File::from_std(file.try_clone()?).metadata()?;
103 native_metadata_identity(&metadata)
104}
105
106#[cfg(not(any(unix, windows)))]
107fn native_root_identity(_: &std::fs::File) -> std::io::Result<NativeRootIdentity> {
108 Err(std::io::Error::new(
109 std::io::ErrorKind::Unsupported,
110 "stable root identity is unavailable on this platform",
111 ))
112}