1//! inotify support for working with inotifies
2
3use super::super::c;
4use crate::backend::fs::syscalls;
5use crate::fd::{BorrowedFd, OwnedFd};
6use crate::io;
7use bitflags::bitflags;
8
9bitflags! {
10 /// `IN_*` for use with [`inotify_init`].
11 ///
12 /// [`inotify_init`]: crate::fs::inotify::inotify_init
13 pub struct CreateFlags: c::c_uint {
14 /// `IN_CLOEXEC`
15 const CLOEXEC = linux_raw_sys::general::IN_CLOEXEC;
16 /// `IN_NONBLOCK`
17 const NONBLOCK = linux_raw_sys::general::IN_NONBLOCK;
18 }
19}
20
21bitflags! {
22 /// `IN*` for use with [`inotify_add_watch`].
23 ///
24 /// [`inotify_add_watch`]: crate::fs::inotify::inotify_add_watch
25 #[derive(Default)]
26 pub struct WatchFlags: c::c_uint {
27 /// `IN_ACCESS`
28 const ACCESS = linux_raw_sys::general::IN_ACCESS;
29 /// `IN_ATTRIB`
30 const ATTRIB = linux_raw_sys::general::IN_ATTRIB;
31 /// `IN_CLOSE_NOWRITE`
32 const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE;
33 /// `IN_CLOSE_WRITE`
34 const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE;
35 /// `IN_CREATE `
36 const CREATE = linux_raw_sys::general::IN_CREATE;
37 /// `IN_DELETE`
38 const DELETE = linux_raw_sys::general::IN_DELETE;
39 /// `IN_DELETE_SELF`
40 const DELETE_SELF = linux_raw_sys::general::IN_DELETE_SELF;
41 /// `IN_MODIFY`
42 const MODIFY = linux_raw_sys::general::IN_MODIFY;
43 /// `IN_MOVE_SELF`
44 const MOVE_SELF = linux_raw_sys::general::IN_MOVE_SELF;
45 /// `IN_MOVED_FROM`
46 const MOVED_FROM = linux_raw_sys::general::IN_MOVED_FROM;
47 /// `IN_MOVED_TO`
48 const MOVED_TO = linux_raw_sys::general::IN_MOVED_TO;
49 /// `IN_OPEN`
50 const OPEN = linux_raw_sys::general::IN_OPEN;
51
52 /// `IN_CLOSE`
53 const CLOSE = linux_raw_sys::general::IN_CLOSE;
54 /// `IN_MOVE`
55 const MOVE = linux_raw_sys::general::IN_MOVE;
56 /// `IN_ALL_EVENTS`
57 const ALL_EVENTS = linux_raw_sys::general::IN_ALL_EVENTS;
58
59 /// `IN_DONT_FOLLOW`
60 const DONT_FOLLOW = linux_raw_sys::general::IN_DONT_FOLLOW;
61 /// `IN_EXCL_UNLINK`
62 const EXCL_UNLINK = linux_raw_sys::general::IN_EXCL_UNLINK;
63 /// `IN_MASK_ADD`
64 const MASK_ADD = linux_raw_sys::general::IN_MASK_ADD;
65 /// `IN_MASK_CREATE`
66 const MASK_CREATE = linux_raw_sys::general::IN_MASK_CREATE;
67 /// `IN_ONESHOT`
68 const ONESHOT = linux_raw_sys::general::IN_ONESHOT;
69 /// `IN_ONLYDIR`
70 const ONLYDIR = linux_raw_sys::general::IN_ONLYDIR;
71 }
72}
73
74/// `inotify_init1(flags)`—Creates a new inotify object.
75///
76/// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file
77/// descriptor from being implicitly passed across `exec` boundaries.
78#[doc(alias = "inotify_init1")]
79#[inline]
80pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> {
81 syscalls::inotify_init1(flags)
82}
83
84/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify.
85///
86/// This registers or updates a watch for the filesystem path `path`
87/// and returns a watch descriptor corresponding to this watch.
88///
89/// Note: Due to the existence of hardlinks, providing two
90/// different paths to this method may result in it returning
91/// the same watch descriptor. An application should keep track of this
92/// externally to avoid logic errors.
93#[inline]
94pub fn inotify_add_watch<P: crate::path::Arg>(
95 inot: BorrowedFd<'_>,
96 path: P,
97 flags: WatchFlags,
98) -> io::Result<i32> {
99 let path: Cow<'_, CStr> = path.as_cow_c_str().unwrap();
100 syscalls::inotify_add_watch(infd:inot, &path, flags)
101}
102
103/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify
104///
105/// The watch descriptor provided should have previously been returned
106/// by [`inotify_add_watch`] and not previously have been removed.
107#[doc(alias = "inotify_rm_watch")]
108#[inline]
109pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> {
110 syscalls::inotify_rm_watch(infd:inot, wfd:wd)
111}
112