inotify/
fd_guard.rs

1use std::{
2    ops::Deref,
3    os::unix::io::{
4        AsFd,
5        AsRawFd,
6        BorrowedFd,
7        FromRawFd,
8        IntoRawFd,
9        RawFd,
10    },
11    sync::atomic::{
12        AtomicBool,
13        Ordering,
14    },
15};
16
17use inotify_sys as ffi;
18
19
20/// A RAII guard around a `RawFd` that closes it automatically on drop.
21#[derive(Debug)]
22pub struct FdGuard {
23    pub(crate) fd           : RawFd,
24    pub(crate) close_on_drop: AtomicBool,
25}
26
27impl FdGuard {
28
29    /// Indicate that the wrapped file descriptor should _not_ be closed
30    /// when the guard is dropped.
31    ///
32    /// This should be called in cases where ownership of the wrapped file
33    /// descriptor has been "moved" out of the guard.
34    ///
35    /// This is factored out into a separate function to ensure that it's
36    /// always used consistently.
37    #[inline]
38    pub fn should_not_close(&self) {
39        self.close_on_drop.store(false, Ordering::Release);
40    }
41}
42
43impl Deref for FdGuard {
44    type Target = RawFd;
45
46    #[inline]
47    fn deref(&self) -> &Self::Target {
48        &self.fd
49    }
50}
51
52impl Drop for FdGuard {
53    fn drop(&mut self) {
54        if self.close_on_drop.load(Ordering::Acquire) {
55            unsafe { ffi::close(self.fd); }
56        }
57    }
58}
59
60impl FromRawFd for FdGuard {
61    unsafe fn from_raw_fd(fd: RawFd) -> Self {
62        FdGuard {
63            fd,
64            close_on_drop: AtomicBool::new(true),
65        }
66    }
67}
68
69impl IntoRawFd for FdGuard {
70    fn into_raw_fd(self) -> RawFd {
71        self.should_not_close();
72        self.fd
73    }
74}
75
76impl AsRawFd for FdGuard {
77    fn as_raw_fd(&self) -> RawFd {
78        self.fd
79    }
80}
81
82impl AsFd for FdGuard {
83    #[inline]
84    fn as_fd(&self) -> BorrowedFd<'_> {
85        unsafe { BorrowedFd::borrow_raw(self.fd) }
86    }
87}
88
89impl PartialEq for FdGuard {
90    fn eq(&self, other: &FdGuard) -> bool {
91        self.fd == other.fd
92    }
93}