I was just learning about how files are handled in Linux and I started wondering how the std::fs::File abstraction was created in rust. However I could not find the relevant code when navigating the code.
std::fs::File has a struct defined like this
pub struct File {
inner: fs_imp::File,
}
So I guessed that I needed to find what fs_imp::File is. Turns out this fs_imp comes from here which is defined at the top of std::fs::File:
use crate::sys::fs as fs_imp;
.
following crate::sys lead me to /.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/mod.rs
At this point I am stumped because this is just a file that looks like this:
#![allow(unsafe_op_in_unsafe_fn)]
/// The PAL (platform abstraction layer) contains platform-specific abstractions
/// for implementing the features in the other submodules, e.g. UNIX file
/// descriptors.
mod pal;
mod personality;
pub mod backtrace;
pub mod cmath;
pub mod exit_guard;
pub mod os_str;
pub mod path;
pub mod sync;
pub mod thread_local;
// FIXME(117276): remove this, move feature implementations into individual
// submodules.
pub use pal::*;
So how can I understand how the Linux version of rust Files work inside the hood?
You just keep following the imports. The only thing that could bring fs
into scope here is the wildcard reexport pub use pal::*;
which leads you to sys/pal/mod.rs
where depending on the platform another module is wildcard reexported:
cfg_if::cfg_if! { if #[cfg(unix)] { mod unix; pub use self::unix::*; } // …
and if we follow for example the unix
path to sys/pal/unix/mod.rs
we finally found the definition of the fs
module and it contains the definition of File
:
pub struct File(FileDesc);
Of course if you have for example rust-analyzer
or something similar setup you can just "goto definition" until you arrive at your target which makes all that manual search a lot easier.