I don't understand what Rust does with a file handle when it goes out of scope. For example, I create a file and write several words into it:
let wd = os::getcwd().unwrap_or(Path::new("/"));
let mut file = File::create(&Path::new("daemon_log.txt"));
file.write_all(format!("DAEMON CWD: {}", wd.as_str().unwrap_or("some problems")).as_bytes());
At the point where file goes out of scope, the compiler should insert instructions to free memory. If my understanding of how blocking IO is usually implemented is correct, then, apart from releasing memory, the process should also release some lock.
What I'm worried about is that in the source for File
, I cannot find any tip for compiler to do it. This old article says that all the magic goes into implementation of the Drop
trait for File
, but it seems that it's not true for now, because I cannot find Drop
trait implementation in either std::ops.rs
nor in std::old_io::fs.rs
.
UPDATE
I checked File
s implementation of write_all
again and found that the write
method works with some descriptor (FileDesc
). I haven't found any related info about it in docs, so went to GitHub and found this. It looks like the answer to my question, but I am confused by one line in the comment:
// closing stdio file handles makes no sense, so never do it
What does this mean? I should never invoke libc::close
on my fd myself? Or they are themselves not sure how it should be implemented?
A file handle, in the context of computing, is a temporary reference number that an operating system assigns to a file requested by a user to be opened. The system calls, accesses and interacts with the file through that reference number throughout the session until the user terminates the file or the system session.
A file handle is a temporary file name or identifier assigned to an open file that is currently being utilized by an operating system. It is sometimes used as a temporary backup for a file being modified.
A temporary reference (typically a number) assigned by the operating system to a file that an application has asked it to open. The handle is used throughout the session to access the file. In the Unix/Linux world, a file handle is called a "file descriptor."
For POSIX platforms, File
is defined as struct File(FileDesc)
in mod sys::fs2
, where FileDesc
is a wrapper around file descriptor number. The destructor of FileDesc
closes the file:
impl Drop for FileDesc {
fn drop(&mut self) {
// closing stdio file handles makes no sense, so never do it. Also, 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.
if self.fd > libc::STDERR_FILENO {
let _ = unsafe { libc::close(self.fd) };
}
}
}
The implementation for Windows platform defines File
as wrapper for Handle
value, the destructor of which calls CloseHandle()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With