zig-system-calls by oven-sh/bun
npx skills add https://github.com/oven-sh/bun --skill zig-system-calls使用 bun.sys 替代 std.fs 或 std.posix,以实现跨平台的系统调用并具备正确的错误处理。
对于大多数文件操作,请使用 bun.sys.File 包装器:
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();
// 读/写
_ = try file.read(buffer).unwrap();
_ = try file.writeAll(data).unwrap();
// 获取文件信息
const stat = try file.stat().unwrap();
const size = try file.getEndPos().unwrap();
// 兼容 std.io
const reader = file.reader();
const writer = file.writer();
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(),
};
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 方面 | bun.sys | std.fs/std.posix |
|---|---|---|
| 返回类型 | 带有详细错误的 Maybe(T) | 通用错误联合体 |
| Windows 支持 | 完全支持,带 libuv 回退 | 有限 / 仅 POSIX |
| 错误信息 | errno、系统调用标签、路径、文件描述符 | 仅 errno |
| EINTR 处理 | 自动重试 | 手动处理 |
bun.sys 函数返回 Maybe(T) —— 一个带标签的联合体:
const sys = bun.sys;
// 模式 1:基于结果/错误的 switch
switch (sys.read(fd, buffer)) {
.result => |bytes_read| {
// 使用 bytes_read
},
.err => |err| {
// err.errno, err.syscall, err.fd, err.path
if (err.getErrno() == .AGAIN) {
// 处理 EAGAIN
}
},
}
// 模式 2:使用 try 解包(转换为 Zig 错误)
const bytes = try sys.read(fd, buffer).unwrap();
// 模式 3:使用默认值解包
const value = sys.stat(path).unwrapOr(default_stat);
仅在 bun.sys.File 无法满足需求时使用这些。
const sys = bun.sys;
// 使用 bun.O 标志(跨平台标准化)
const fd = switch (sys.open(path, bun.O.RDONLY, 0)) {
.result => |fd| fd,
.err => |err| return .{ .err = err },
};
defer fd.close();
// 常用标志
bun.O.RDONLY, bun.O.WRONLY, bun.O.RDWR
bun.O.CREAT, bun.O.TRUNC, bun.O.APPEND
bun.O.NONBLOCK, bun.O.DIRECTORY
// 单次读取(可能返回少于缓冲区大小)
switch (sys.read(fd, buffer)) {
.result => |n| { /* 读取了 n 个字节 */ },
.err => |err| { /* 处理错误 */ },
}
// 读取直到 EOF 或缓冲区满
const total = try sys.readAll(fd, buffer).unwrap();
// 基于位置的读/写
sys.pread(fd, buffer, offset)
sys.pwrite(fd, data, offset)
// 向量 I/O
sys.readv(fd, iovecs)
sys.writev(fd, iovecs)
sys.stat(path) // 跟随符号链接
sys.lstat(path) // 不跟随符号链接
sys.fstat(fd) // 来自文件描述符
sys.fstatat(fd, path)
// 仅限 Linux:更快的选择性 stat
sys.statx(path, &.{ .size, .mtime })
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)
sys.chmod(path, mode)
sys.fchmod(fd, mode)
sys.fchmodat(fd, path, mode, flags)
sys.chown(path, uid, gid)
sys.fchown(fd, uid, gid)
关闭操作在 bun.FD 上:
fd.close(); // 出错时断言(在 defer 中使用)
// 或者如果你需要错误信息:
if (fd.closeAllowingBadFileDescriptor(null)) |err| {
// 处理错误
}
var buf: bun.PathBuffer = undefined;
const cwd = try sys.getcwd(&buf).unwrap();
const cwdZ = try sys.getcwdZ(&buf).unwrap(); // 零终止
sys.chdir(path, destination)
使用 bun.DirIterator 替代 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 等
} else {
break; // 目录结束
}
},
.err => |err| return .{ .err = err },
}
}
重要:bun.sys 对套接字的支持有限。对于网络 I/O:
uws.Socket(libuwebsockets)PipeReader.zig 和 PipeWriter.zigbun.sys 中可用的操作:
sys.setsockopt(fd, level, optname, value)
sys.socketpair(domain, socktype, protocol, nonblocking_status)
请不要使用 bun.sys 进行套接字读/写——请改用 uws.Socket。
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)
const err: bun.sys.Error = ...;
err.errno // 原始 errno 值
err.getErrno() // 作为 std.posix.E 枚举
err.syscall // 哪个系统调用失败(Tag 枚举)
err.fd // 可选:文件描述符
err.path // 可选:路径字符串
bun.sys.File 包装器bun.sys 函数bun.O.* 标志而非 std.os.O.*.unwrap() 处理 Maybe(T)defer fd.close() 进行清理uws.Socket 而非 bun.sys每周安装量
101
代码仓库
GitHub 星标数
88.4K
首次出现
2026年1月22日
安全审计
安装于
opencode96
codex92
gemini-cli91
github-copilot88
claude-code87
cursor86
Use bun.sys instead of std.fs or std.posix for cross-platform syscalls with proper error handling.
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();
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(),
};
}
| 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 |
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);
Only use these when bun.sys.File doesn't meet your needs.
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
// 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)
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 })
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)
sys.chmod(path, mode)
sys.fchmod(fd, mode)
sys.fchmodat(fd, path, mode, flags)
sys.chown(path, uid, gid)
sys.fchown(fd, uid, gid)
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
}
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)
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 },
}
}
Important : bun.sys has limited socket support. For network I/O:
uws.Socket (libuwebsockets) exclusivelyPipeReader.zig and PipeWriter.zigAvailable 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.
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)
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
bun.sys.File wrapper for most file operationsbun.sys functions only when neededbun.O.* flags instead of std.os.O.*Maybe(T) with switch or .unwrap()defer fd.close() for cleanupuws.Socket not bun.sysWeekly Installs
101
Repository
GitHub Stars
88.4K
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode96
codex92
gemini-cli91
github-copilot88
claude-code87
cursor86
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
120,000 周安装
Brave Search 本地描述 API:获取 AI 生成的本地商家描述,增强搜索结果与旅行指南
74 周安装
Google图片搜索技能:AI智能选图,自动化配图与Obsidian笔记增强工具
245 周安装
AWS Lambda PHP 集成指南:使用Bref部署Symfony应用与冷启动优化
249 周安装
HL7 IHE PAM 消息解析器 - 解析验证医疗患者管理ADT消息,支持HL7 v2.5标准
74 周安装
AWS Lambda Java 集成指南:Micronaut与原生Java优化冷启动性能
248 周安装
腾讯云CloudBase开发指南:云函数、Web认证、小程序集成与MCP配置
251 周安装