1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! inotify support for working with inotifies

use crate::backend::c;
use crate::backend::fs::syscalls;
use crate::fd::{BorrowedFd, OwnedFd};
use crate::io;
use bitflags::bitflags;

bitflags! {
    /// `IN_*` for use with [`inotify_init`].
    ///
    /// [`inotify_init`]: crate::fs::inotify::inotify_init
    #[repr(transparent)]
    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
    pub struct CreateFlags: c::c_uint {
        /// `IN_CLOEXEC`
        const CLOEXEC = linux_raw_sys::general::IN_CLOEXEC;
        /// `IN_NONBLOCK`
        const NONBLOCK = linux_raw_sys::general::IN_NONBLOCK;

        /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags>
        const _ = !0;
    }
}

bitflags! {
    /// `IN*` for use with [`inotify_add_watch`].
    ///
    /// [`inotify_add_watch`]: crate::fs::inotify::inotify_add_watch
    #[repr(transparent)]
    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
    pub struct WatchFlags: c::c_uint {
        /// `IN_ACCESS`
        const ACCESS = linux_raw_sys::general::IN_ACCESS;
        /// `IN_ATTRIB`
        const ATTRIB = linux_raw_sys::general::IN_ATTRIB;
        /// `IN_CLOSE_NOWRITE`
        const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE;
        /// `IN_CLOSE_WRITE`
        const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE;
        /// `IN_CREATE `
        const CREATE = linux_raw_sys::general::IN_CREATE;
        /// `IN_DELETE`
        const DELETE = linux_raw_sys::general::IN_DELETE;
        /// `IN_DELETE_SELF`
        const DELETE_SELF = linux_raw_sys::general::IN_DELETE_SELF;
        /// `IN_MODIFY`
        const MODIFY = linux_raw_sys::general::IN_MODIFY;
        /// `IN_MOVE_SELF`
        const MOVE_SELF = linux_raw_sys::general::IN_MOVE_SELF;
        /// `IN_MOVED_FROM`
        const MOVED_FROM = linux_raw_sys::general::IN_MOVED_FROM;
        /// `IN_MOVED_TO`
        const MOVED_TO = linux_raw_sys::general::IN_MOVED_TO;
        /// `IN_OPEN`
        const OPEN = linux_raw_sys::general::IN_OPEN;

        /// `IN_CLOSE`
        const CLOSE = linux_raw_sys::general::IN_CLOSE;
        /// `IN_MOVE`
        const MOVE = linux_raw_sys::general::IN_MOVE;
        /// `IN_ALL_EVENTS`
        const ALL_EVENTS = linux_raw_sys::general::IN_ALL_EVENTS;

        /// `IN_DONT_FOLLOW`
        const DONT_FOLLOW = linux_raw_sys::general::IN_DONT_FOLLOW;
        /// `IN_EXCL_UNLINK`
        const EXCL_UNLINK = linux_raw_sys::general::IN_EXCL_UNLINK;
        /// `IN_MASK_ADD`
        const MASK_ADD = linux_raw_sys::general::IN_MASK_ADD;
        /// `IN_MASK_CREATE`
        const MASK_CREATE = linux_raw_sys::general::IN_MASK_CREATE;
        /// `IN_ONESHOT`
        const ONESHOT = linux_raw_sys::general::IN_ONESHOT;
        /// `IN_ONLYDIR`
        const ONLYDIR = linux_raw_sys::general::IN_ONLYDIR;

        /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags>
        const _ = !0;
    }
}

/// `inotify_init1(flags)`—Creates a new inotify object.
///
/// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file
/// descriptor from being implicitly passed across `exec` boundaries.
#[doc(alias = "inotify_init1")]
#[inline]
pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> {
    syscalls::inotify_init1(flags)
}

/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify.
///
/// This registers or updates a watch for the filesystem path `path`
/// and returns a watch descriptor corresponding to this watch.
///
/// Note: Due to the existence of hardlinks, providing two
/// different paths to this method may result in it returning
/// the same watch descriptor. An application should keep track of this
/// externally to avoid logic errors.
#[inline]
pub fn inotify_add_watch<P: crate::path::Arg>(
    inot: BorrowedFd<'_>,
    path: P,
    flags: WatchFlags,
) -> io::Result<i32> {
    path.into_with_c_str(|path| syscalls::inotify_add_watch(inot, path, flags))
}

/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify
///
/// The watch descriptor provided should have previously been returned by
/// [`inotify_add_watch`] and not previously have been removed.
#[doc(alias = "inotify_rm_watch")]
#[inline]
pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> {
    syscalls::inotify_rm_watch(inot, wd)
}