diff options
author | Steve Lau <stevelauc@outlook.com> | 2022-12-09 15:33:27 +0800 |
---|---|---|
committer | Steve Lau <stevelauc@outlook.com> | 2022-12-09 15:33:27 +0800 |
commit | f592678301e30fa51b0149ca37f42b5c7ea5657e (patch) | |
tree | 41ce883f0bbd0c239ada484f07120d53b9d66184 /src/sys | |
parent | a2356abe578dc822dbaf4386fbc17a63385ba0f8 (diff) | |
download | nix-f592678301e30fa51b0149ca37f42b5c7ea5657e.zip |
feat: I/O safety for 'sys/timerfd'
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/timerfd.rs | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs index a35fc927..90a05a8c 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -33,24 +33,28 @@ pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags}; use crate::unistd::read; use crate::{errno::Errno, Result}; use libc::c_int; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}; /// A timerfd instance. This is also a file descriptor, you can feed it to -/// other interfaces consuming file descriptors, epoll for example. +/// other interfaces taking file descriptors as arguments, [`epoll`] for example. +/// +/// [`epoll`]: crate::sys::epoll #[derive(Debug)] pub struct TimerFd { - fd: RawFd, + fd: OwnedFd, } -impl AsRawFd for TimerFd { - fn as_raw_fd(&self) -> RawFd { - self.fd +impl AsFd for TimerFd { + fn as_fd(&self) -> BorrowedFd<'_> { + self.fd.as_fd() } } impl FromRawFd for TimerFd { unsafe fn from_raw_fd(fd: RawFd) -> Self { - TimerFd { fd } + TimerFd { + fd: OwnedFd::from_raw_fd(fd), + } } } @@ -97,7 +101,9 @@ impl TimerFd { Errno::result(unsafe { libc::timerfd_create(clockid as i32, flags.bits()) }) - .map(|fd| Self { fd }) + .map(|fd| Self { + fd: unsafe { OwnedFd::from_raw_fd(fd) }, + }) } /// Sets a new alarm on the timer. @@ -145,7 +151,7 @@ impl TimerFd { let timerspec: TimerSpec = expiration.into(); Errno::result(unsafe { libc::timerfd_settime( - self.fd, + self.fd.as_fd().as_raw_fd(), flags.bits(), timerspec.as_ref(), std::ptr::null_mut(), @@ -159,7 +165,10 @@ impl TimerFd { pub fn get(&self) -> Result<Option<Expiration>> { let mut timerspec = TimerSpec::none(); Errno::result(unsafe { - libc::timerfd_gettime(self.fd, timerspec.as_mut()) + libc::timerfd_gettime( + self.fd.as_fd().as_raw_fd(), + timerspec.as_mut(), + ) }) .map(|_| { if timerspec.as_ref().it_interval.tv_sec == 0 @@ -179,7 +188,7 @@ impl TimerFd { pub fn unset(&self) -> Result<()> { Errno::result(unsafe { libc::timerfd_settime( - self.fd, + self.fd.as_fd().as_raw_fd(), TimerSetTimeFlags::empty().bits(), TimerSpec::none().as_ref(), std::ptr::null_mut(), @@ -192,7 +201,7 @@ impl TimerFd { /// /// Note: If the alarm is unset, then you will wait forever. pub fn wait(&self) -> Result<()> { - while let Err(e) = read(self.fd, &mut [0u8; 8]) { + while let Err(e) = read(self.fd.as_fd().as_raw_fd(), &mut [0u8; 8]) { if e != Errno::EINTR { return Err(e); } @@ -201,14 +210,3 @@ impl TimerFd { Ok(()) } } - -impl Drop for TimerFd { - fn drop(&mut self) { - if !std::thread::panicking() { - let result = Errno::result(unsafe { libc::close(self.fd) }); - if let Err(Errno::EBADF) = result { - panic!("close of TimerFd encountered EBADF"); - } - } - } -} |