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