mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 16:45:27 +00:00
56 lines
1.8 KiB
Zig
56 lines
1.8 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const mem = std.mem;
|
|
const math = std.math;
|
|
const fs = std.fs;
|
|
const assert = std.debug.assert;
|
|
const Allocator = mem.Allocator;
|
|
const wasi = std.os.wasi;
|
|
const fd_t = wasi.fd_t;
|
|
const prestat_t = wasi.prestat_t;
|
|
|
|
pub const Preopens = struct {
|
|
// Indexed by file descriptor number.
|
|
names: []const []const u8,
|
|
|
|
pub fn find(p: Preopens, name: []const u8) ?std.posix.fd_t {
|
|
for (p.names, 0..) |elem_name, i| {
|
|
if (mem.eql(u8, elem_name, name)) {
|
|
return @intCast(i);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
};
|
|
|
|
pub fn preopensAlloc(gpa: Allocator) Allocator.Error!Preopens {
|
|
var names: std.ArrayListUnmanaged([]const u8) = .empty;
|
|
defer names.deinit(gpa);
|
|
|
|
try names.ensureUnusedCapacity(gpa, 3);
|
|
|
|
names.appendAssumeCapacity("stdin"); // 0
|
|
names.appendAssumeCapacity("stdout"); // 1
|
|
names.appendAssumeCapacity("stderr"); // 2
|
|
while (true) {
|
|
const fd = @as(wasi.fd_t, @intCast(names.items.len));
|
|
var prestat: prestat_t = undefined;
|
|
switch (wasi.fd_prestat_get(fd, &prestat)) {
|
|
.SUCCESS => {},
|
|
.OPNOTSUPP, .BADF => return .{ .names = try names.toOwnedSlice(gpa) },
|
|
else => @panic("fd_prestat_get: unexpected error"),
|
|
}
|
|
try names.ensureUnusedCapacity(gpa, 1);
|
|
// This length does not include a null byte. Let's keep it this way to
|
|
// gently encourage WASI implementations to behave properly.
|
|
const name_len = prestat.u.dir.pr_name_len;
|
|
const name = try gpa.alloc(u8, name_len);
|
|
errdefer gpa.free(name);
|
|
switch (wasi.fd_prestat_dir_name(fd, name.ptr, name.len)) {
|
|
.SUCCESS => {},
|
|
else => @panic("fd_prestat_dir_name: unexpected error"),
|
|
}
|
|
names.appendAssumeCapacity(name);
|
|
}
|
|
}
|