Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic if an OwnedFd carried a bad file descriptor #124518

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 13 additions & 6 deletions library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,24 @@ impl Drop for OwnedFd {
#[inline]
fn drop(&mut self) {
unsafe {
// Note that errors are ignored when closing a file descriptor. The
// reason for this is that if an error occurs we don't actually know if
// the file descriptor was closed or not, and if we retried (for
// something like EINTR), we might close another valid file descriptor
// opened after we closed ours.
#[cfg(not(target_os = "hermit"))]
{
#[cfg(unix)]
crate::sys::fs::debug_assert_fd_is_open(self.fd);

let _ = libc::close(self.fd);
match cvt(libc::close(self.fd)) {
Ok(_) => {},
Err(err) if err.raw_os_error() == Some(libc::EBADF) {
panic!("`OwnedFd` held an invalid file descriptor");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug_assert_fd_is_open (added in #124210) checks if the file descriptor actually existed. The reason that PR doesn't just check the result of close is because a FUSE filesystem can return EBADF from close even if the fd actually exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm. I see.

It's sad that there's no way to return an error here, would be nice if the user could somehow be alerted to this problem even in release mode.

Copy link
Member

@the8472 the8472 Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the right way to do that is to add an explicit fn close(self) -> Result method. Whether everyone is onboard with that is a separate question.

}
// Note that errors are ignored when closing a file
// descriptor. The reason for this is that if an error
// occurs we don't actually know if the file descriptor was
// closed or not, and if we retried (for something like
// EINTR), we might close another valid file descriptor
// opened after we closed ours.
Err(_) => {}
}
}
#[cfg(target_os = "hermit")]
let _ = hermit_abi::close(self.fd);
Expand Down