1use std::{ffi, io};
2
3use crate::{Error, Result};
4
5#[repr(C)]
7#[allow(non_snake_case)]
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct file_handle {
10 handle_bytes: u8,
11 handle_type: i32,
12 f_handle: *mut u8,
13}
14
15impl file_handle {
16 pub const fn new() -> Self {
18 Self {
19 handle_bytes: 0,
20 handle_type: 0,
21 f_handle: std::ptr::null_mut(),
22 }
23 }
24
25 pub fn as_ptr(&self) -> *const Self {
26 self as *const _
27 }
28
29 pub fn as_void_ptr(&self) -> *const ffi::c_void {
30 self.as_ptr() as *const _
31 }
32
33 pub fn as_ptr_mut(&mut self) -> *mut Self {
34 self as *mut _
35 }
36
37 pub fn as_void_ptr_mut(&mut self) -> *mut ffi::c_void {
38 self.as_ptr_mut() as *mut _
39 }
40}
41
42impl Default for file_handle {
43 fn default() -> Self {
44 Self::new()
45 }
46}
47
48pub fn name_to_handle_at(
50 dir_fd: i32,
51 path: &str,
52 handle: &mut file_handle,
53 mount_id: &mut i32,
54 flags: i32,
55) -> Result<()> {
56 let path_str = ffi::CString::new(path)?;
57
58 let ret = unsafe {
60 libc::syscall(
61 libc::SYS_name_to_handle_at,
62 dir_fd,
63 path_str.as_ptr(),
64 handle.as_void_ptr_mut(),
65 mount_id as *mut i32,
66 flags,
67 )
68 };
69
70 if ret == 0 {
71 Ok(())
72 } else {
73 let errno = io::Error::last_os_error();
74 let errmsg = format!("error calling `name_to_handle_at`, ret: {ret}, errno: {errno}");
75
76 log::warn!("{errmsg}");
77
78 Err(Error::io(errno.kind(), errmsg))
79 }
80}