zig-system-calls

System Calls & File I/O in Zig

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "zig-system-calls" with this command: npx skills add oven-sh/bun/oven-sh-bun-zig-system-calls

System Calls & File I/O in Zig

Use bun.sys instead of std.fs or std.posix for cross-platform syscalls with proper error handling.

bun.sys.File (Preferred)

For most file operations, use the bun.sys.File wrapper:

const File = bun.sys.File;

const file = switch (File.open(path, bun.O.RDWR, 0o644)) { .result => |f| f, .err => |err| return .{ .err = err }, }; defer file.close();

// Read/write _ = try file.read(buffer).unwrap(); _ = try file.writeAll(data).unwrap();

// Get file info const stat = try file.stat().unwrap(); const size = try file.getEndPos().unwrap();

// std.io compatible const reader = file.reader(); const writer = file.writer();

Complete Example

const File = bun.sys.File;

pub fn writeFile(path: [:0]const u8, data: []const u8) File.WriteError!void { const file = switch (File.open(path, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) { .result => |f| f, .err => |err| return err.toError(), }; defer file.close();

_ = switch (file.writeAll(data)) {
    .result => {},
    .err => |err| return err.toError(),
};

}

Why bun.sys?

Aspect bun.sys std.fs/std.posix

Return Type Maybe(T) with detailed Error Generic error union

Windows Full support with libuv fallback Limited/POSIX-only

Error Info errno, syscall tag, path, fd errno only

EINTR Automatic retry Manual handling

Error Handling with Maybe(T)

bun.sys functions return Maybe(T)

  • a tagged union:

const sys = bun.sys;

// Pattern 1: Switch on result/error switch (sys.read(fd, buffer)) { .result => |bytes_read| { // use bytes_read }, .err => |err| { // err.errno, err.syscall, err.fd, err.path if (err.getErrno() == .AGAIN) { // handle EAGAIN } }, }

// Pattern 2: Unwrap with try (converts to Zig error) const bytes = try sys.read(fd, buffer).unwrap();

// Pattern 3: Unwrap with default const value = sys.stat(path).unwrapOr(default_stat);

Low-Level File Operations

Only use these when bun.sys.File doesn't meet your needs.

Opening Files

const sys = bun.sys;

// Use bun.O flags (cross-platform normalized) const fd = switch (sys.open(path, bun.O.RDONLY, 0)) { .result => |fd| fd, .err => |err| return .{ .err = err }, }; defer fd.close();

// Common flags bun.O.RDONLY, bun.O.WRONLY, bun.O.RDWR bun.O.CREAT, bun.O.TRUNC, bun.O.APPEND bun.O.NONBLOCK, bun.O.DIRECTORY

Reading & Writing

// Single read (may return less than buffer size) switch (sys.read(fd, buffer)) { .result => |n| { /* n bytes read / }, .err => |err| { / handle error */ }, }

// Read until EOF or buffer full const total = try sys.readAll(fd, buffer).unwrap();

// Position-based read/write sys.pread(fd, buffer, offset) sys.pwrite(fd, data, offset)

// Vector I/O sys.readv(fd, iovecs) sys.writev(fd, iovecs)

File Info

sys.stat(path) // Follow symlinks sys.lstat(path) // Don't follow symlinks sys.fstat(fd) // From file descriptor sys.fstatat(fd, path)

// Linux-only: faster selective stat sys.statx(path, &.{ .size, .mtime })

Path Operations

sys.unlink(path) sys.unlinkat(dir_fd, path) sys.rename(from, to) sys.renameat(from_dir, from, to_dir, to) sys.readlink(path, buf) sys.readlinkat(fd, path, buf) sys.link(T, src, dest) sys.linkat(src_fd, src, dest_fd, dest) sys.symlink(target, dest) sys.symlinkat(target, dirfd, dest) sys.mkdir(path, mode) sys.mkdirat(dir_fd, path, mode) sys.rmdir(path)

Permissions

sys.chmod(path, mode) sys.fchmod(fd, mode) sys.fchmodat(fd, path, mode, flags) sys.chown(path, uid, gid) sys.fchown(fd, uid, gid)

Closing File Descriptors

Close is on bun.FD :

fd.close(); // Asserts on error (use in defer)

// Or if you need error info: if (fd.closeAllowingBadFileDescriptor(null)) |err| { // handle error }

Directory Operations

var buf: bun.PathBuffer = undefined; const cwd = try sys.getcwd(&buf).unwrap(); const cwdZ = try sys.getcwdZ(&buf).unwrap(); // Zero-terminated sys.chdir(path, destination)

Directory Iteration

Use bun.DirIterator instead of std.fs.Dir.Iterator :

var iter = bun.iterateDir(dir_fd); while (true) { switch (iter.next()) { .result => |entry| { if (entry) |e| { const name = e.name.slice(); const kind = e.kind; // .file, .directory, .sym_link, etc. } else { break; // End of directory } }, .err => |err| return .{ .err = err }, } }

Socket Operations

Important: bun.sys has limited socket support. For network I/O:

  • Non-blocking sockets: Use uws.Socket (libuwebsockets) exclusively

  • Pipes/blocking I/O: Use PipeReader.zig and PipeWriter.zig

Available in bun.sys:

sys.setsockopt(fd, level, optname, value) sys.socketpair(domain, socktype, protocol, nonblocking_status)

Do NOT use bun.sys for socket read/write - use uws.Socket instead.

Other Operations

sys.ftruncate(fd, size) sys.lseek(fd, offset, whence) sys.dup(fd) sys.dupWithFlags(fd, flags) sys.fcntl(fd, cmd, arg) sys.pipe() sys.mmap(...) sys.munmap(memory) sys.access(path, mode) sys.futimens(fd, atime, mtime) sys.utimens(path, atime, mtime)

Error Type

const err: bun.sys.Error = ...; err.errno // Raw errno value err.getErrno() // As std.posix.E enum err.syscall // Which syscall failed (Tag enum) err.fd // Optional: file descriptor err.path // Optional: path string

Key Points

  • Prefer bun.sys.File wrapper for most file operations

  • Use low-level bun.sys functions only when needed

  • Use bun.O.* flags instead of std.os.O.*

  • Handle Maybe(T) with switch or .unwrap()

  • Use defer fd.close() for cleanup

  • EINTR is handled automatically in most functions

  • For sockets, use uws.Socket not bun.sys

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

implementing-jsc-classes-zig

No summary provided by upstream source.

Repository SourceNeeds Review
General

writing-bundler-tests

No summary provided by upstream source.

Repository SourceNeeds Review
General

implementing-jsc-classes-cpp

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

writing-dev-server-tests

No summary provided by upstream source.

Repository SourceNeeds Review