starnix_modules_inotify/
syscalls.rs1use crate::inotify::InotifyFileObject;
6use starnix_core::security;
7use starnix_core::task::CurrentTask;
8use starnix_core::vfs::syscalls::{LookupFlags, lookup_at};
9use starnix_core::vfs::{FdFlags, FdNumber, WdNumber};
10
11use starnix_uapi::errors::Errno;
12use starnix_uapi::inotify_mask::InotifyMask;
13use starnix_uapi::user_address::UserCString;
14use starnix_uapi::{IN_CLOEXEC, IN_NONBLOCK, errno, error};
15
16pub fn sys_inotify_init1(current_task: &CurrentTask, flags: u32) -> Result<FdNumber, Errno> {
17 if flags & !(IN_NONBLOCK | IN_CLOEXEC) != 0 {
18 return error!(EINVAL);
19 }
20 let non_blocking = flags & IN_NONBLOCK != 0;
21 let close_on_exec = flags & IN_CLOEXEC != 0;
22 let inotify_file = InotifyFileObject::new_file(current_task, non_blocking);
23 let fd_flags = if close_on_exec { FdFlags::CLOEXEC } else { FdFlags::empty() };
24 current_task.add_file(inotify_file, fd_flags)
25}
26
27pub fn sys_inotify_init(current_task: &CurrentTask) -> Result<FdNumber, Errno> {
28 sys_inotify_init1(current_task, 0)
29}
30
31pub fn sys_inotify_add_watch(
32 current_task: &CurrentTask,
33 fd: FdNumber,
34 user_path: UserCString,
35 mask: u32,
36) -> Result<WdNumber, Errno> {
37 let mask = InotifyMask::from_bits(mask).ok_or_else(|| errno!(EINVAL))?;
38 if !mask.intersects(InotifyMask::ALL_EVENTS) {
39 return error!(EINVAL);
41 }
42 let file = current_task.files().get(fd)?;
43 let inotify_file = file.downcast_file::<InotifyFileObject>().ok_or_else(|| errno!(EINVAL))?;
44 let options = if mask.contains(InotifyMask::DONT_FOLLOW) {
45 LookupFlags::no_follow()
46 } else {
47 LookupFlags::default()
48 };
49 let watched_node = lookup_at(current_task, FdNumber::AT_FDCWD, user_path, options)?;
50 if mask.contains(InotifyMask::ONLYDIR) && !watched_node.entry.node.is_dir() {
51 return error!(ENOTDIR);
52 }
53 security::path_notify(current_task, &watched_node.entry.node, mask)?;
54 inotify_file.add_watch(watched_node.entry, mask, &file)
55}
56
57pub fn sys_inotify_rm_watch(
58 current_task: &CurrentTask,
59 fd: FdNumber,
60 watch_id: WdNumber,
61) -> Result<(), Errno> {
62 let file = current_task.files().get(fd)?;
63 let inotify_file = file.downcast_file::<InotifyFileObject>().ok_or_else(|| errno!(EINVAL))?;
64 inotify_file.remove_watch(watch_id, &file)
65}
66
67pub fn sys_arch32_inotify_init1(current_task: &CurrentTask, flags: u32) -> Result<FdNumber, Errno> {
68 sys_inotify_init1(current_task, flags)
69}
70
71pub fn sys_arch32_inotify_init(current_task: &CurrentTask) -> Result<FdNumber, Errno> {
72 sys_inotify_init1(current_task, 0)
73}
74
75pub fn sys_arch32_inotify_add_watch(
76 current_task: &CurrentTask,
77 fd: FdNumber,
78 user_path: UserCString,
79 mask: u32,
80) -> Result<WdNumber, Errno> {
81 sys_inotify_add_watch(current_task, fd, user_path, mask)
82}
83
84pub fn sys_arch32_inotify_rm_watch(
85 current_task: &CurrentTask,
86 fd: FdNumber,
87 watch_id: WdNumber,
88) -> Result<(), Errno> {
89 sys_inotify_rm_watch(current_task, fd, watch_id)
90}