
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
Async file I/O for Linux using io_uring.
io_uring is Linux's modern async I/O interface. It's fast and efficient, but the raw API requires managing submission queues, completion queues, memory lifetimes, and substantial unsafe code. This crate builds on io-uring to provide simple async/await file operations at three levels of abstraction.
1. High-level functions β Similar to std::fs, but async. Suitable for scripts, tools, and straightforward file operations.
let contents = uring_file::fs::read_to_string("config.toml").await?;
2. The default ring β The UringFile trait works on any file handle. Useful when you have files opened elsewhere and want io_uring performance without managing a ring.
use uring_file::UringFile;
let file = std::fs::File::open("data.bin")?;
let result = file.ur_read_at(0, 4096).await?;
3. Custom rings β Full control over ring configuration. Configure queue size, enable kernel polling, register files for faster repeated access.
use uring_file::uring::{Uring, UringCfg};
let ring = Uring::new(UringCfg {
entries: 256,
kernel_poll: true,
..Default::default()
})?;
All three use the same underlying io_uring implementation. Uring is Clone + Send + Sync, and path arguments accept any type implementing AsRef<Path>.
[dependencies]
uring-file = "0.4"
tokio = { version = "1", features = ["rt", "macros"] }
use uring_file::fs;
#[tokio::main]
async fn main() -> std::io::Result<()> {
fs::write("/tmp/hello.txt", "Hello!").await?;
let text = fs::read_to_string("/tmp/hello.txt").await?;
fs::create_dir_all("/tmp/a/b/c").await?;
fs::remove_dir_all("/tmp/a").await?;
Ok(())
}
See docs.rs for full documentation.
uring_file::fs β high-level convenience// Reading
fs::read(path).await?; // -> Vec<u8>
fs::read_to_string(path).await?; // -> String
// Writing
fs::write(path, data).await?; // create or truncate
fs::append(path, data).await?; // create or append
fs::copy(src, dst).await?; // -> bytes copied
// Opening files (returns tokio::fs::File)
let file = fs::open(path).await?; // read-only
let file = fs::create(path).await?; // write, create/truncate
// OpenOptions for more control
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path).await?;
// Directories
fs::create_dir(path).await?;
fs::create_dir_all(path).await?;
fs::remove_dir(path).await?;
fs::remove_dir_all(path).await?;
// Files and links
fs::remove_file(path).await?;
fs::rename(from, to).await?;
fs::symlink(target, link).await?;
fs::hard_link(original, link).await?;
fs::truncate(path, len).await?;
// Metadata
fs::metadata(path).await?; // -> Metadata
fs::exists(path).await; // -> bool
UringFile trait β for existing file handlesWorks with std::fs::File and tokio::fs::File:
use uring_file::UringFile;
let file = std::fs::File::open("data.bin")?;
// Positioned I/O
let result = file.ur_read_at(offset, len).await?;
let result = file.ur_write_at(offset, data).await?;
// Durability
file.ur_sync().await?; // fsync
file.ur_datasync().await?; // fdatasync
// Metadata and space management
file.ur_statx().await?;
file.ur_fallocate(offset, len, mode).await?;
file.ur_fadvise(offset, len, advice).await?;
file.ur_ftruncate(len).await?;
Uring β full controluse uring_file::uring::{Uring, UringCfg};
let ring = Uring::new(UringCfg {
entries: 256, // submission queue size
kernel_poll: true, // SQPOLL for lower latency
..Default::default()
})?;
// File operations
let fd = ring.open("/tmp/file", libc::O_RDWR | libc::O_CREAT, 0o644).await?;
ring.write_at(&fd, 0, b"hello".to_vec()).await?;
ring.read_at(&fd, 0, 5).await?;
ring.close(fd).await?;
// Path operations
ring.mkdir("/tmp/dir", 0o755).await?;
ring.rename("/tmp/a", "/tmp/b").await?;
ring.unlink("/tmp/file").await?;
// Registered files for faster repeated access
let registered = ring.register(&file)?;
ring.read_at(®istered, 0, 1024).await?;
| Feature | Minimum kernel |
|---|---|
| Basic read/write/sync | 5.1 |
| open, statx, fallocate, fadvise | 5.6 |
| close, rename, unlink, mkdir, symlink, link | 5.11 |
| ftruncate | 6.9 |
No readdir in io_uring β remove_dir_all uses tokio for directory listing, then io_uring for deletions. This is a kernel limitation.
~2GB per operation β Single read/write operations are limited to approximately 2GB (uring::URING_LEN_MAX). Chunk larger transfers.
βββββββββββββββ βββββββββββββββββββββ βββββββββββββββ
β Async tasks ββββββΆβ Submission thread ββββββΆβ io_uring β
βββββββββββββββ βββββββββββββββββββββ ββββββββ¬βββββββ
β² β
β βββββββββββββββββββββ β
ββββββββββββββ Completion thread ββββββββββββββ
βββββββββββββββββββββ
Async tasks send requests to a submission thread that batches them into the io_uring submission queue. A completion thread polls for results and wakes the appropriate futures.
MIT OR Apache-2.0
FAQs
Unknown package
We found that uring-file demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: whatβs affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.