Skip to content

Commit 07c1e44

Browse files
committed
linux: add fanotify(7) API bindings.
The `fanotify` API[0] is a linux-specific API for notification and interception of filesystem events. In some ways it is similar to `inotify`, but with different advantages/tradeoffs. It is particularly well suited to full filesystem/mount monitoring (vs per directory) and for allowing/denying access to files (`inotify` lacks this capability). The `fanotify` API has been updated several times since it was enabled in Linux 2.6.37. Presently I've only included support for the original `fanotify` features, and the `FAN_MARK_FILESYSTEM` addition made in Linux 4.20. There are subsequent updates in 5.0 and 5.1 not covered in this initial commit. This commit adds the relevant constants and types from `uapi/linux/fanotify.h`[1] and two new functions (`fanotify_init`[2] and `fanotify_wrap`[3]) to `src/unix/linux_like/linux/mod.rs`. While I believe this API is also present on Android I have presently limited my attention to Linux. Although this commit focuses on Linux 4.20.x's `fanotify` API/constants I have skipped adding constants for `FAN_ALL_CLASS_BITS`, `FAN_ALL_INIT_FLAGS`, `FAN_ALL_MARK_FLAGS`, `FAN_ALL_EVENTS`, `FAN_ALL_PERM_EVENTS` and `FAN_ALL_OUTGOING_EVENTS` even though they are present in this kernel version's headers. These defines were deprecated[4] in later releases with instructions to not use them in new programs or extend them with new values. It would be a shame for new Rust programs to use deprecated #defines! [0]: http://man7.org/linux/man-pages/man7/fanotify.7.html [1]: https://github.com/torvalds/linux/blob/d54f4fba889b205e9cd8239182ca5d27d0ac3bc2/include/uapi/linux/fanotify.h [2]: http://man7.org/linux/man-pages/man2/fanotify_init.2.html [3]: http://man7.org/linux/man-pages/man2/fanotify_mark.2.html [4]: torvalds/linux@23c9dee#diff-4c9ca62be6bf38cc08f7ea9daf16e379
1 parent 39f43b5 commit 07c1e44

File tree

1 file changed

+73
-0
lines changed
  • src/unix/linux_like/linux

1 file changed

+73
-0
lines changed

src/unix/linux_like/linux/mod.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,21 @@ s! {
477477
pub len: u32
478478
}
479479

480+
pub struct fanotify_event_metadata {
481+
pub len: u32,
482+
pub vers: u8,
483+
pub reserved: u8,
484+
pub metadata_len: u16,
485+
pub mask_align: u64,
486+
pub fd: ::c_int,
487+
pub pid: ::c_int,
488+
}
489+
490+
pub struct fanotify_response {
491+
pub fd: ::c_int,
492+
pub response: u32,
493+
}
494+
480495
pub struct sockaddr_vm {
481496
pub svm_family: ::sa_family_t,
482497
pub svm_reserved1: ::c_ushort,
@@ -2417,6 +2432,56 @@ pub const IN_ALL_EVENTS: u32 = IN_ACCESS
24172432
pub const IN_CLOEXEC: ::c_int = O_CLOEXEC;
24182433
pub const IN_NONBLOCK: ::c_int = O_NONBLOCK;
24192434

2435+
// uapi/linux/fanotify.h
2436+
pub const FAN_ACCESS: ::c_ulonglong = 0x0000_0001;
2437+
pub const FAN_MODIFY: ::c_ulonglong = 0x0000_0002;
2438+
pub const FAN_CLOSE_WRITE: ::c_ulonglong = 0x0000_0008;
2439+
pub const FAN_CLOSE_NOWRITE: ::c_ulonglong = 0x0000_0010;
2440+
pub const FAN_OPEN: ::c_ulonglong = 0x0000_0020;
2441+
2442+
pub const FAN_Q_OVERFLOW: ::c_ulonglong = 0x0000_4000;
2443+
2444+
pub const FAN_OPEN_PERM: ::c_ulonglong = 0x0001_0000;
2445+
pub const FAN_ACCESS_PERM: ::c_ulonglong = 0x0002_0000;
2446+
2447+
pub const FAN_ONDIR: ::c_ulonglong = 0x4000_0000;
2448+
2449+
pub const FAN_EVENT_ON_CHILD: ::c_ulonglong = 0x0800_0000;
2450+
2451+
pub const FAN_CLOSE: ::c_ulonglong = FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE;
2452+
2453+
pub const FAN_CLOEXEC: ::c_int = 0x0000_0001;
2454+
pub const FAN_NONBLOCK: ::c_int = 0x0000_0002;
2455+
2456+
pub const FAN_CLASS_NOTIF: ::c_int = 0x0000_0000;
2457+
pub const FAN_CLASS_CONTENT: ::c_int = 0x0000_0004;
2458+
pub const FAN_CLASS_PRE_CONTENT: ::c_int = 0x0000_0008;
2459+
2460+
pub const FAN_UNLIMITED_QUEUE: ::c_int = 0x0000_0010;
2461+
pub const FAN_UNLIMITED_MARKS: ::c_int = 0x0000_0020;
2462+
2463+
pub const FAN_MARK_ADD: ::c_int = 0x0000_0001;
2464+
pub const FAN_MARK_REMOVE: ::c_int = 0x0000_0002;
2465+
pub const FAN_MARK_DONT_FOLLOW: ::c_int = 0x0000_0004;
2466+
pub const FAN_MARK_ONLYDIR: ::c_int = 0x0000_0008;
2467+
pub const FAN_MARK_INODE: ::c_int = 0x0000_0000;
2468+
pub const FAN_MARK_MOUNT: ::c_int = 0x0000_0010;
2469+
// NOTE: FAN_MARK_FILESYSTEM requires Linux Kernel >= 4.20.0
2470+
pub const FAN_MARK_FILESYSTEM: ::c_int = 0x0000_0100;
2471+
pub const FAN_MARK_IGNORED_MASK: ::c_int = 0x0000_0020;
2472+
pub const FAN_MARK_IGNORED_SURV_MODIFY: ::c_int = 0x0000_0040;
2473+
pub const FAN_MARK_FLUSH: ::c_int = 0x0000_0080;
2474+
2475+
pub const FAN_MARK_TYPE_MASK: ::c_int =
2476+
FAN_MARK_INODE | FAN_MARK_MOUNT | FAN_MARK_FILESYSTEM;
2477+
2478+
pub const FANOTIFY_METADATA_VERSION: u8 = 3;
2479+
2480+
pub const FAN_ALLOW: u32 = 0x01;
2481+
pub const FAN_DENY: u32 = 0x02;
2482+
2483+
pub const FAN_NOFD: ::c_int = 1;
2484+
24202485
pub const FUTEX_WAIT: ::c_int = 0;
24212486
pub const FUTEX_WAKE: ::c_int = 1;
24222487
pub const FUTEX_FD: ::c_int = 2;
@@ -3328,6 +3393,14 @@ extern "C" {
33283393
path: *const ::c_char,
33293394
mask: u32,
33303395
) -> ::c_int;
3396+
pub fn fanotify_init(flags: ::c_int, event_f_flags: ::c_int) -> ::c_int;
3397+
pub fn fanotify_mark(
3398+
fd: ::c_int,
3399+
flags: ::c_int,
3400+
mask: ::c_ulonglong,
3401+
dirfd: ::c_int,
3402+
path: *const ::c_char,
3403+
) -> ::c_int;
33313404
}
33323405

33333406
cfg_if! {

0 commit comments

Comments
 (0)