Skip to content

Commit 8f93634

Browse files
committed
feat: I/O safety for 'sys/memfd' & 'sys/event' & 'sys/eventfd'
1 parent 7f18847 commit 8f93634

File tree

4 files changed

+54
-38
lines changed

4 files changed

+54
-38
lines changed

src/sys/epoll.rs

+40-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::errno::Errno;
22
use crate::Result;
33
use libc::{self, c_int};
44
use std::mem;
5-
use std::os::unix::io::{FromRawFd,RawFd, OwnedFd, AsFd, AsRawFd};
5+
use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
66

77
libc_bitflags!(
88
pub struct EpollFlags: c_int {
@@ -78,22 +78,22 @@ impl EpollEvent {
7878
/// # fn main() -> nix::Result<()> {
7979
/// const DATA: u64 = 17;
8080
/// const MILLIS: u64 = 100;
81-
///
81+
///
8282
/// // Create epoll
8383
/// let epoll = Epoll::new(EpollCreateFlags::empty())?;
84-
///
84+
///
8585
/// // Create eventfd & Add event
86-
/// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) };
86+
/// let eventfd = unsafe { eventfd(0, EfdFlags::empty())? };
8787
/// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
88-
///
88+
///
8989
/// // Arm eventfd & Time wait
9090
/// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
9191
/// let now = Instant::now();
92-
///
92+
///
9393
/// // Wait on event
9494
/// let mut events = [EpollEvent::empty()];
9595
/// epoll.wait(&mut events, MILLIS as isize)?;
96-
///
96+
///
9797
/// // Assert data correct & timeout didn't occur
9898
/// assert_eq!(events[0].data(), DATA);
9999
/// assert!(now.elapsed() < Duration::from_millis(MILLIS));
@@ -104,7 +104,7 @@ impl EpollEvent {
104104
pub struct Epoll(pub OwnedFd);
105105
impl Epoll {
106106
/// Creates a new epoll instance and returns a file descriptor referring to that instance.
107-
///
107+
///
108108
/// [`epoll_create1`](https://man7.org/linux/man-pages/man2/epoll_create1.2.html).
109109
pub fn new(flags: EpollCreateFlags) -> Result<Self> {
110110
let res = unsafe { libc::epoll_create1(flags.bits()) };
@@ -113,30 +113,38 @@ impl Epoll {
113113
Ok(Self(owned_fd))
114114
}
115115
/// Add an entry to the interest list of the epoll file descriptor for
116-
/// specified in events.
117-
///
116+
/// specified in events.
117+
///
118118
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_ADD`.
119119
pub fn add<Fd: AsFd>(&self, fd: Fd, mut event: EpollEvent) -> Result<()> {
120-
self.epoll_ctl(EpollOp::EpollCtlAdd,fd,&mut event)
120+
self.epoll_ctl(EpollOp::EpollCtlAdd, fd, &mut event)
121121
}
122122
/// Remove (deregister) the target file descriptor `fd` from the interest list.
123-
///
123+
///
124124
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_DEL` .
125125
pub fn delete<Fd: AsFd>(&self, fd: Fd) -> Result<()> {
126-
self.epoll_ctl(EpollOp::EpollCtlDel,fd,None)
126+
self.epoll_ctl(EpollOp::EpollCtlDel, fd, None)
127127
}
128128
/// Change the settings associated with `fd` in the interest list to the new settings specified
129129
/// in `event`.
130-
///
130+
///
131131
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_MOD`.
132-
pub fn modify<Fd: AsFd>(&self,fd: Fd, event: &mut EpollEvent) -> Result<()> {
133-
self.epoll_ctl(EpollOp::EpollCtlMod,fd,event)
132+
pub fn modify<Fd: AsFd>(
133+
&self,
134+
fd: Fd,
135+
event: &mut EpollEvent,
136+
) -> Result<()> {
137+
self.epoll_ctl(EpollOp::EpollCtlMod, fd, event)
134138
}
135139
/// Waits for I/O events, blocking the calling thread if no events are currently available.
136140
/// (This can be thought of as fetching items from the ready list of the epoll instance.)
137-
///
141+
///
138142
/// [`epoll_wait`](https://man7.org/linux/man-pages/man2/epoll_wait.2.html)
139-
pub fn wait(&self, events: &mut [EpollEvent], timeout: isize) -> Result<usize> {
143+
pub fn wait(
144+
&self,
145+
events: &mut [EpollEvent],
146+
timeout: isize,
147+
) -> Result<usize> {
140148
let res = unsafe {
141149
libc::epoll_wait(
142150
self.0.as_raw_fd(),
@@ -145,15 +153,15 @@ impl Epoll {
145153
timeout as c_int,
146154
)
147155
};
148-
156+
149157
Errno::result(res).map(|r| r as usize)
150158
}
151159
/// This system call is used to add, modify, or remove entries in the interest list of the epoll
152160
/// instance referred to by `self`. It requests that the operation `op` be performed for the
153161
/// target file descriptor, `fd`.
154-
///
162+
///
155163
/// When possible prefer [`Epoll::add`], [`Epoll::delete`] and [`Epoll::modify`].
156-
///
164+
///
157165
/// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
158166
fn epoll_ctl<'a, Fd: AsFd, T>(
159167
&self,
@@ -165,9 +173,17 @@ impl Epoll {
165173
T: Into<Option<&'a mut EpollEvent>>,
166174
{
167175
let event: Option<&mut EpollEvent> = event.into();
168-
let ptr = event.map(|x|&mut x.event as *mut libc::epoll_event).unwrap_or(std::ptr::null_mut());
176+
let ptr = event
177+
.map(|x| &mut x.event as *mut libc::epoll_event)
178+
.unwrap_or(std::ptr::null_mut());
169179
unsafe {
170-
Errno::result(libc::epoll_ctl(self.0.as_raw_fd(), op as c_int, fd.as_fd().as_raw_fd(), ptr)).map(drop)
180+
Errno::result(libc::epoll_ctl(
181+
self.0.as_raw_fd(),
182+
op as c_int,
183+
fd.as_fd().as_raw_fd(),
184+
ptr,
185+
))
186+
.map(drop)
171187
}
172188
}
173189
}
@@ -231,4 +247,4 @@ pub fn epoll_wait(
231247
};
232248

233249
Errno::result(res).map(|r| r as usize)
234-
}
250+
}

src/sys/event.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use libc::{c_int, c_long, intptr_t, time_t, timespec, uintptr_t};
88
use libc::{c_long, intptr_t, size_t, time_t, timespec, uintptr_t};
99
use std::convert::TryInto;
1010
use std::mem;
11-
use std::os::unix::io::RawFd;
11+
use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd};
1212
use std::ptr;
1313

1414
// Redefine kevent in terms of programmer-friendly enums and bitfields.
@@ -207,10 +207,10 @@ libc_bitflags!(
207207
}
208208
);
209209

210-
pub fn kqueue() -> Result<RawFd> {
210+
pub fn kqueue() -> Result<OwnedFd> {
211211
let res = unsafe { libc::kqueue() };
212212

213-
Errno::result(res)
213+
Errno::result(res).map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
214214
}
215215

216216
// KEvent can't derive Send because on some operating systems, udata is defined
@@ -267,8 +267,8 @@ impl KEvent {
267267
}
268268
}
269269

270-
pub fn kevent(
271-
kq: RawFd,
270+
pub fn kevent<Fd: AsFd>(
271+
kq: Fd,
272272
changelist: &[KEvent],
273273
eventlist: &mut [KEvent],
274274
timeout_ms: usize,
@@ -293,15 +293,15 @@ type type_of_nchanges = c_int;
293293
#[cfg(target_os = "netbsd")]
294294
type type_of_nchanges = size_t;
295295

296-
pub fn kevent_ts(
297-
kq: RawFd,
296+
pub fn kevent_ts<Fd: AsFd>(
297+
kq: Fd,
298298
changelist: &[KEvent],
299299
eventlist: &mut [KEvent],
300300
timeout_opt: Option<timespec>,
301301
) -> Result<usize> {
302302
let res = unsafe {
303303
libc::kevent(
304-
kq,
304+
kq.as_fd().as_raw_fd(),
305305
changelist.as_ptr() as *const libc::kevent,
306306
changelist.len() as type_of_nchanges,
307307
eventlist.as_mut_ptr() as *mut libc::kevent,

src/sys/eventfd.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::errno::Errno;
22
use crate::Result;
3-
use std::os::unix::io::RawFd;
3+
use std::os::unix::io::{FromRawFd, OwnedFd};
44

55
libc_bitflags! {
66
pub struct EfdFlags: libc::c_int {
@@ -10,8 +10,8 @@ libc_bitflags! {
1010
}
1111
}
1212

13-
pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
13+
pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<OwnedFd> {
1414
let res = unsafe { libc::eventfd(initval, flags.bits()) };
1515

16-
Errno::result(res).map(|r| r as RawFd)
16+
Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r) })
1717
}

src/sys/memfd.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Interfaces for managing memory-backed files.
22
33
use cfg_if::cfg_if;
4-
use std::os::unix::io::RawFd;
4+
use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
55

66
use crate::errno::Errno;
77
use crate::Result;
@@ -40,7 +40,7 @@ libc_bitflags!(
4040
/// For more information, see [`memfd_create(2)`].
4141
///
4242
/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
43-
pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
43+
pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<OwnedFd> {
4444
let res = unsafe {
4545
cfg_if! {
4646
if #[cfg(all(
@@ -60,5 +60,5 @@ pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
6060
}
6161
};
6262

63-
Errno::result(res).map(|r| r as RawFd)
63+
Errno::result(res).map(|r| unsafe { OwnedFd::from_raw_fd(r as RawFd) })
6464
}

0 commit comments

Comments
 (0)