1use std::{
2 ops::Deref,
3 os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd},
4 sync::atomic::{AtomicBool, Ordering},
5};
6
7use inotify_sys as ffi;
8
9#[derive(Debug)]
11pub struct FdGuard {
12 pub(crate) fd: RawFd,
13 pub(crate) close_on_drop: AtomicBool,
14}
15
16impl FdGuard {
17 #[inline]
26 pub fn should_not_close(&self) {
27 self.close_on_drop.store(false, Ordering::Release);
28 }
29}
30
31impl Deref for FdGuard {
32 type Target = RawFd;
33
34 #[inline]
35 fn deref(&self) -> &Self::Target {
36 &self.fd
37 }
38}
39
40impl Drop for FdGuard {
41 fn drop(&mut self) {
42 if self.close_on_drop.load(Ordering::Acquire) {
43 unsafe {
44 ffi::close(self.fd);
45 }
46 }
47 }
48}
49
50impl FromRawFd for FdGuard {
51 unsafe fn from_raw_fd(fd: RawFd) -> Self {
52 FdGuard {
53 fd,
54 close_on_drop: AtomicBool::new(true),
55 }
56 }
57}
58
59impl IntoRawFd for FdGuard {
60 fn into_raw_fd(self) -> RawFd {
61 self.should_not_close();
62 self.fd
63 }
64}
65
66impl AsRawFd for FdGuard {
67 fn as_raw_fd(&self) -> RawFd {
68 self.fd
69 }
70}
71
72impl AsFd for FdGuard {
73 #[inline]
74 fn as_fd(&self) -> BorrowedFd<'_> {
75 unsafe { BorrowedFd::borrow_raw(self.fd) }
76 }
77}
78
79impl PartialEq for FdGuard {
80 fn eq(&self, other: &FdGuard) -> bool {
81 self.fd == other.fd
82 }
83}