Skip to content

Commit 9d74330

Browse files
committed
feat: I/O safety for 'sys/inotify'
1 parent 67f7d46 commit 9d74330

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

src/sys/inotify.rs

+11-17
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use libc::{c_char, c_int};
3232
use std::ffi::{CStr, OsStr, OsString};
3333
use std::mem::{size_of, MaybeUninit};
3434
use std::os::unix::ffi::OsStrExt;
35-
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
35+
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
3636
use std::ptr;
3737

3838
libc_bitflags! {
@@ -101,9 +101,9 @@ libc_bitflags! {
101101

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

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

146-
res.map(|fd| Inotify { fd })
146+
res.map(|fd| Inotify { fd: unsafe { OwnedFd::from_raw_fd(fd) } })
147147
}
148148

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

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

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

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

200200
while (nread - offset) >= header_size {
201201
let event = unsafe {
@@ -235,14 +235,8 @@ impl Inotify {
235235
}
236236
}
237237

238-
impl AsRawFd for Inotify {
239-
fn as_raw_fd(&self) -> RawFd {
240-
self.fd
241-
}
242-
}
243-
244238
impl FromRawFd for Inotify {
245239
unsafe fn from_raw_fd(fd: RawFd) -> Self {
246-
Inotify { fd }
240+
Inotify { fd: OwnedFd::from_raw_fd(fd) }
247241
}
248242
}

0 commit comments

Comments
 (0)