Open
Description
While working on #98209 , I went searching for where close() is called. I found it in std/src/os/fd/owned.rs:
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.
let _ = libc::close(self.fd);
}
}
}
The Linux close(2) manpage states:
A careful programmer will check the return value of close(), since it is quite possi‐
ble that errors on a previous write(2) operation are reported only on the final
close() that releases the open file description. Failing to check the return value
when closing a file may lead to silent loss of data. This can especially be observed
with NFS and with disk quota.
Note, however, that a failure return should be used only for diagnostic purposes
(i.e., a warning to the application that there may still be I/O pending or there may
have been failed I/O) or remedial purposes (e.g., writing the file once more or creat‐
ing a backup).
Retrying the close() after a failure return is the wrong thing to do, since this may
Anyhow, checking the return value of close(2) is necessary in a number of cases. But here we have a conundrum, because what can we possibly do with a failure of close(2) inside a Drop impl?
- Ignore it as now
- Panic
- More complex options (eg, allow the caller to register a close-failure callback with the underlying File/whatever object)
These all have their pros and cons. But aren't we looking for something more like this?
fn close(self) -> io::Result<()>
In fact, a Close
trait could define this function and it could be implemented on files, pipes, sockets, etc.
Meta
rustc --version --verbose
:
rustc 1.56.1 (59eed8a2a 2021-11-01)
binary: rustc
commit-hash: 59eed8a2aac0230a8b53e89d4e99d55912ba6b35
commit-date: 2021-11-01
host: x86_64-unknown-linux-gnu
release: 1.56.1
LLVM version: 13.0.0