diff --git a/CHANGELOG.md b/CHANGELOG.md index c18d70cf51..a00679d9b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed ### Fixed +- `TimerFd` now closes the underlying fd on drop. + ([#1381](https://github.com/nix-rust/nix/pull/1381)) - Define `*_MAGIC` filesystem constants on Linux s390x (#[1372](https://github.com/nix-rust/nix/pull/1372)) - mqueue, sysinfo, timespec, statfs, test_ptrace_syscall() on x32 @@ -39,6 +41,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Removed `SockLevel`, which hasn't been used for a few years (#[1362](https://github.com/nix-rust/nix/pull/1362)) +- Removed both `Copy` and `Clone` from `TimerFd`. + ([#1381](https://github.com/nix-rust/nix/pull/1381)) ## [0.19.1] - 28 November 2020 ### Fixed diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs index 3086309e62..4a24719498 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -37,7 +37,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; /// A timerfd 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 TimerFd { fd: RawFd, } @@ -166,7 +166,7 @@ pub enum Expiration { impl TimerFd { /// Creates a new timer based on the clock defined by `clockid`. The /// underlying fd can be assigned specific flags with `flags` (CLOEXEC, - /// NONBLOCK). + /// NONBLOCK). The underlying fd will be closed on drop. pub fn new(clockid: ClockId, flags: TimerFlags) -> Result { Errno::result(unsafe { libc::timerfd_create(clockid as i32, flags.bits()) }) .map(|fd| Self { fd }) @@ -270,3 +270,16 @@ 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(Error::Sys(Errno::EBADF)) = result { + panic!("close of TimerFd encountered EBADF"); + } + } + } +}