diff --git a/src/backend/libc/fs/inotify.rs b/src/backend/libc/fs/inotify.rs index 2044bd945..3be68c7cf 100644 --- a/src/backend/libc/fs/inotify.rs +++ b/src/backend/libc/fs/inotify.rs @@ -1,9 +1,6 @@ //! inotify support for working with inotifies use crate::backend::c; -use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; use bitflags::bitflags; bitflags! { @@ -79,53 +76,3 @@ bitflags! { 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")] -pub fn inotify_init(flags: CreateFlags) -> io::Result { - // SAFETY: `inotify_init1` has no safety preconditions. - unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(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. -pub fn inotify_add_watch( - inot: BorrowedFd<'_>, - path: P, - flags: WatchFlags, -) -> io::Result { - path.into_with_c_str(|path| { - // SAFETY: The fd and path we are passing is guaranteed valid by the - // type system. - unsafe { - ret_c_int(c::inotify_add_watch( - borrowed_fd(inot), - c_str(path), - flags.bits(), - )) - } - }) -} - -/// `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")] -pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { - // Android's `inotify_rm_watch` takes `u32` despite that - // `inotify_add_watch` expects a `i32`. - #[cfg(target_os = "android")] - let wd = wd as u32; - // SAFETY: The fd is valid and closing an arbitrary wd is valid. - unsafe { ret(c::inotify_rm_watch(borrowed_fd(inot), wd)) } -} diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index af615ff74..a2204fe34 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -2549,3 +2549,39 @@ fn test_sizes() { #[cfg(fix_y2038)] assert!(core::mem::size_of::<[c::timespec; 2]>() < core::mem::size_of::()); } + +#[inline] +#[cfg(linux_kernel)] +pub(crate) fn inotify_init1(flags: super::inotify::CreateFlags) -> io::Result { + // SAFETY: `inotify_init1` has no safety preconditions. + unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(flags))) } +} + +#[inline] +#[cfg(linux_kernel)] +pub(crate) fn inotify_add_watch( + inot: BorrowedFd<'_>, + path: &CStr, + flags: super::inotify::WatchFlags, +) -> io::Result { + // SAFETY: The fd and path we are passing is guaranteed valid by the + // type system. + unsafe { + ret_c_int(c::inotify_add_watch( + borrowed_fd(inot), + c_str(path), + flags.bits(), + )) + } +} + +#[inline] +#[cfg(linux_kernel)] +pub(crate) fn inotify_rm_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { + // Android's `inotify_rm_watch` takes `u32` despite that + // `inotify_add_watch` expects a `i32`. + #[cfg(target_os = "android")] + let wd = wd as u32; + // SAFETY: The fd is valid and closing an arbitrary wd is valid. + unsafe { ret(c::inotify_rm_watch(borrowed_fd(inot), wd)) } +} diff --git a/src/backend/linux_raw/fs/inotify.rs b/src/backend/linux_raw/fs/inotify.rs index 851335ba8..1876e8349 100644 --- a/src/backend/linux_raw/fs/inotify.rs +++ b/src/backend/linux_raw/fs/inotify.rs @@ -1,9 +1,6 @@ //! 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! { @@ -79,40 +76,3 @@ bitflags! { 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 { - 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( - inot: BorrowedFd<'_>, - path: P, - flags: WatchFlags, -) -> io::Result { - 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) -} diff --git a/src/fs/inotify.rs b/src/fs/inotify.rs new file mode 100644 index 000000000..addcfda57 --- /dev/null +++ b/src/fs/inotify.rs @@ -0,0 +1,43 @@ +//! inotify support for working with inotifies + +pub use crate::backend::fs::inotify::{CreateFlags, WatchFlags}; +use crate::backend::fs::syscalls; +use crate::fd::{AsFd, OwnedFd}; +use crate::io; + +/// `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 { + 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( + inot: impl AsFd, + path: P, + flags: WatchFlags, +) -> io::Result { + path.into_with_c_str(|path| syscalls::inotify_add_watch(inot.as_fd(), 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: impl AsFd, wd: i32) -> io::Result<()> { + syscalls::inotify_rm_watch(inot.as_fd(), wd) +} diff --git a/src/fs/mod.rs b/src/fs/mod.rs index 477a82ee9..13a6d29cd 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -33,6 +33,8 @@ mod getpath; #[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. mod id; #[cfg(linux_kernel)] +pub mod inotify; +#[cfg(linux_kernel)] mod ioctl; #[cfg(not(any( target_os = "espidf", @@ -66,8 +68,6 @@ mod sync; #[cfg(any(apple, linux_kernel, target_os = "hurd"))] mod xattr; -#[cfg(linux_kernel)] -pub use crate::backend::fs::inotify; pub use abs::*; #[cfg(not(target_os = "redox"))] pub use at::*;