Low-Level Systems Programming
Platform-Specific APIs
While std::fs, std::net, and std::process expose the portable intersection of operating system features, std::os provides zero-cost extension traits (*Ext) for Unix (std::os::unix), Linux (std::os::linux), macOS (std::os::darwin), Windows (std::os::windows), and WebAssembly (std::os::wasi).
+-------------------------------------------------------------------+
| Portable Standard Library |
| `std::fs::File`, `std::fs::Metadata`, `OsStr` |
+-------------------------------------------------------------------+
| |
`#[cfg(unix)]` `#[cfg(windows)]`
v v
+---------------------------------+ +-------------------------------+
| `std::os::unix` | | `std::os::windows` |
| - `fs::FileExt` (`read_at`) | | - `fs::FileExt` (`seek_read`) |
| - `fs::MetadataExt` (`ino`, | | - `fs::MetadataExt` |
| `uid`, `gid`, `mode`) | | (`file_attributes`) |
| - `ffi::OsStrExt` (`as_bytes`) | | - `ffi::OsStrExt` |
| - `net::UnixStream` / `Listener`| | (`encode_wide` UTF-16) |
+---------------------------------+ +-------------------------------+
Key Extension Traits in std::os::unix and std::os::windows
| Extension Trait | Module (unix / windows) |
Capabilities Unlocked on Standard Types |
|---|---|---|
FileExt |
std::os::*::fs::FileExt |
Positional reads/writes (pread/pwrite on Unix via read_at/write_at, seek_read/seek_write on Windows) using &File concurrently across threads without mutating the file cursor! |
MetadataExt |
std::os::*::fs::MetadataExt |
Unix inode (ino()), device ID (dev()), owner (uid(), gid()), hard-link count (nlink()), and Windows file_attributes(). |
PermissionsExt |
std::os::unix::fs::PermissionsExt |
Reading and setting 12-bit Unix octal permission modes (0o755, 0o600, setuid/sticky bits). |
OsStrExt / OsStringExt |
std::os::*::ffi |
Zero-copy conversion between &OsStr and raw &[u8] bytes on Unix, or UTF-16 encode_wide() iterators on Windows. |
UnixStream / UnixListener |
std::os::unix::net |
High-speed local Inter-Process Communication (IPC) over Unix Domain Sockets (AF_UNIX). |
Concurrent Positional File I/O with FileExt (pread / pwrite)
Normally, reading from a std::fs::File advances the kernel file offset, requiring &mut File (or a Mutex<File> across threads). On Unix, std::os::unix::fs::FileExt::read_exact_at(&self, buf, offset) invokes the pread syscall, allowing multiple threads to read from different offsets of a shared &File simultaneously with zero locking:
use std::env;
use std::fs::{self, File};
use std::io::{self, Write};
use std::thread;
fn read_chunk_at(file: &File, offset: u64, buf: &mut [u8]) -> io::Result<()> {
#[cfg(unix)]
{
use std::os::unix::fs::FileExt;
file.read_exact_at(buf, offset)
}
#[cfg(windows)]
{
use std::os::windows::fs::FileExt;
let mut read_total = 0;
while read_total < buf.len() {
let n = file.seek_read(&mut buf[read_total..], offset + read_total as u64)?;
if n == 0 {
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "early EOF"));
}
read_total += n;
}
Ok(())
}
}
fn main() -> io::Result<()> {
let path = env::temp_dir().join("rust_ch59_pread_demo.bin");
{
let mut f = File::create(&path)?;
f.write_all(b"BLOCK_00BLOCK_01BLOCK_02BLOCK_03")?;
}
let shared_file = File::open(&path)?;
// Four threads read distinct 8-byte blocks from `&shared_file` concurrently without a Mutex!
thread::scope(|s| {
for block_idx in 0..4u64 {
let file_ref = &shared_file;
s.spawn(move || {
let mut buf = [0u8; 8];
read_chunk_at(file_ref, block_idx * 8, &mut buf).unwrap();
let expected = format!("BLOCK_0{block_idx}");
assert_eq!(&buf, expected.as_bytes());
});
}
});
println!("Concurrent lock-free positional reads verified across 4 threads");
fs::remove_file(&path)?;
Ok(())
}
Concurrent lock-free positional reads verified across 4 threads