Skip to content

Commit

Permalink
feat: I/O safety for 'sys/inotify'
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveLauC committed Dec 9, 2022
1 parent 67f7d46 commit 9d74330
Showing 1 changed file with 11 additions and 17 deletions.
28 changes: 11 additions & 17 deletions src/sys/inotify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use libc::{c_char, c_int};
use std::ffi::{CStr, OsStr, OsString};
use std::mem::{size_of, MaybeUninit};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;

libc_bitflags! {
Expand Down Expand Up @@ -101,9 +101,9 @@ libc_bitflags! {

/// An inotify instance. This is also a file descriptor, you can feed it to
/// other interfaces consuming file descriptors, epoll for example.
#[derive(Debug, Clone, Copy)]
#[derive(Debug)]
pub struct Inotify {
fd: RawFd,
fd: OwnedFd,
}

/// This object is returned when you create a new watch on an inotify instance.
Expand Down Expand Up @@ -143,7 +143,7 @@ impl Inotify {
pub fn init(flags: InitFlags) -> Result<Inotify> {
let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });

res.map(|fd| Inotify { fd })
res.map(|fd| Inotify { fd: unsafe { OwnedFd::from_raw_fd(fd) } })
}

/// Adds a new watch on the target file or directory.
Expand All @@ -152,12 +152,12 @@ impl Inotify {
///
/// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
pub fn add_watch<P: ?Sized + NixPath>(
self,
&self,
path: &P,
mask: AddWatchFlags,
) -> Result<WatchDescriptor> {
let res = path.with_nix_path(|cstr| unsafe {
libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
libc::inotify_add_watch(self.fd.as_raw_fd(), cstr.as_ptr(), mask.bits())
})?;

Errno::result(res).map(|wd| WatchDescriptor { wd })
Expand All @@ -169,15 +169,15 @@ impl Inotify {
/// Returns an EINVAL error if the watch descriptor is invalid.
///
/// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
cfg_if! {
if #[cfg(target_os = "linux")] {
let arg = wd.wd;
} else if #[cfg(target_os = "android")] {
let arg = wd.wd as u32;
}
}
let res = unsafe { libc::inotify_rm_watch(self.fd, arg) };
let res = unsafe { libc::inotify_rm_watch(self.fd.as_raw_fd(), arg) };

Errno::result(res).map(drop)
}
Expand All @@ -188,14 +188,14 @@ impl Inotify {
///
/// Returns as many events as available. If the call was non blocking and no
/// events could be read then the EAGAIN error is returned.
pub fn read_events(self) -> Result<Vec<InotifyEvent>> {
pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
let header_size = size_of::<libc::inotify_event>();
const BUFSIZ: usize = 4096;
let mut buffer = [0u8; BUFSIZ];
let mut events = Vec::new();
let mut offset = 0;

let nread = read(self.fd, &mut buffer)?;
let nread = read(self.fd.as_raw_fd(), &mut buffer)?;

while (nread - offset) >= header_size {
let event = unsafe {
Expand Down Expand Up @@ -235,14 +235,8 @@ impl Inotify {
}
}

impl AsRawFd for Inotify {
fn as_raw_fd(&self) -> RawFd {
self.fd
}
}

impl FromRawFd for Inotify {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
Inotify { fd }
Inotify { fd: OwnedFd::from_raw_fd(fd) }
}
}

0 comments on commit 9d74330

Please sign in to comment.