OpenParable
Skip to content
← Back to skills

Rust System Calls

Development
rust-system-calls

Rust System Calls is an Agent Skill for development published in the oven-sh/bun repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.

Guides using bun_sys for system calls and file I/O in Rust. Use when implementing file operations, opening fds, or any syscall path instead of std::fs or libc.

View on GitHub ↗
QUICK START

How to use this skill

Bring this guide into your coding agent with a prompt tailored to the tool you use.

  1. Open your project in Codex.
  2. Copy and paste the prompt below.
  3. Review files and risks before approving any action.
Prompt to paste
Inspect the Agent Skill at https://github.com/oven-sh/bun/blob/HEAD/.claude/skills/rust-system-calls/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/rust-system-calls, but wait for my approval before writing files or running scripts.

Copying this prompt does not install or run the skill. Review third-party files before use.

System Calls & File I/O in Rust

Use bun_sys instead of std::fs or raw libc for cross-platform syscalls with proper error handling.

bun_sys::File (Preferred)

For most file operations, use the bun_sys::File wrapper. It owns the fd and closes on Drop.

use bun_sys::{File, Fd, O};

let file = File::openat(Fd::cwd(), b"path/to/file", O::RDONLY, 0)?;
let mut buf = vec![0u8; 4096];
let n = file.read_all(&mut buf)?;     // loops until EOF or full
// `file` closes on Drop.

Complete Example

use bun_sys::{File, Fd, O};

pub fn write_file(path: &[u8], data: &[u8]) -> Result<(), bun_sys::Error> {
    let file = File::openat(Fd::cwd(), path, O::WRONLY | O::CREAT | O::TRUNC, 0o664)?;
    file.write_all(data)?;
    Ok(())
}

Why bun_sys?

Aspectbun_sysstd::fs / libc
Return TypeMaybe<T> with rich Errorio::Error (lossy)
WindowsFull support with libuv fallbackIncomplete/POSIX-ish
Error Infoerrno, syscall tag, path, fderrno only
EINTRAutomatic retryManual handling
Paths&[u8] (WTF-8 safe)&Path (UTF-8 lossy)

Error Handling with Maybe

bun_sys functions return Maybe<T> = Result<T, bun_sys::Error>. Propagate with ?; convert to a JS exception via bun_sys_jsc::ErrorJsc::to_js:

use bun_sys_jsc::ErrorJsc;
use bun_sys::{File, Fd, O};

let file = match File::openat(Fd::cwd(), path, O::RDONLY, 0) {
    Ok(f) => f,
    Err(err) => return Ok(err.to_js(global)?),
};

bun_sys::Error carries errno, syscall: Tag, and path: Box<[u8]>. To branch on errno:

match bun_sys::unlink(path) {
    Ok(()) => {}
    Err(e) if e.errno() == bun_c::ENOENT => {} // already gone
    Err(e) => return Err(e),
}

Key Types and Functions

  • Fd (bun_core::Fd) — cross-platform file descriptor. Fd::cwd(), Fd::stdin()/stdout()/stderr(), fd.close().
  • File::open(path: &ZStr, flags, mode) / File::openat(dir: Fd, path: &[u8], flags, mode) / File::make_open(...) (creates parent dirs) / File::create(dir, path, truncate)
  • file.read(buf) / read_all(buf) / read_to_end() / read_to_end_small() / write(buf) / write_all(buf)
  • bun_sys::open, read, write, pread, pwrite, stat, fstat, lstat, mkdir, unlink, rename, symlink, chmod — free fns over Fd
  • Open flags: bun_sys::O::RDONLY, O::WRONLY | O::CREAT | O::TRUNC, etc.

Path Buffers

Use bun_paths for joining/normalization and the path-buffer pool to avoid 64 KB stack allocations on Windows:

use bun_paths::{path_buffer_pool, resolve_path::{self, platform}};

let mut buf = path_buffer_pool::get();
let joined = resolve_path::join_string_buf::<platform::Auto>(&mut *buf, &[dir, name]);
let file = File::openat(Fd::cwd(), joined, O::RDONLY, 0)?;

Common Mistakes

  • Don't .unwrap() a bun_sys result that user input or the OS can cause to fail at runtime — return the error.
  • Don't use std::fs::File — it loses the syscall tag and path needed for Node-compatible error objects.
  • Don't allocate PathBuffer on the stack in hot paths — use path_buffer_pool::get().
  • Don't forget Drop alone closes a File — never file.fd().close() while the File is still live (double close).

See src/CLAUDE.md for the full bun_core/bun_sys reference.