Commit dd238352a4
lib/std/os/wasi.zig
@@ -4,6 +4,7 @@
const std = @import("std");
const mem = std.mem;
const assert = std.debug.assert;
+const Allocator = mem.Allocator;
pub usingnamespace @import("bits.zig");
@@ -21,51 +22,6 @@ comptime {
pub const iovec_t = iovec;
pub const ciovec_t = iovec_const;
-fn is_prefix(preopen: []const u8, path: []const u8) bool {
- if (preopen.len > path.len) {
- return false;
- }
- var i: usize = 0;
- while (i < preopen.len) {
- std.debug.warn("{} == {}", .{ preopen[i], path[i] });
- if (preopen[i] != path[i]) {
- return false;
- }
- i += 1;
- }
- return true;
-}
-
-pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t {
- var fd: fd_t = 3; // start fd has to be beyond stdio fds
- var preopen_path = [_]u8{0} ** PATH_MAX;
-
- while (true) {
- var buf: prestat_t = undefined;
- switch (fd_prestat_get(fd, &buf)) {
- ESUCCESS => {},
- EBADF => {
- break;
- },
- else => |err| return err,
- }
- const preopen_len = buf.u.dir.pr_name_len;
- switch (fd_prestat_dir_name(fd, &preopen_path, preopen_len)) {
- ESUCCESS => {},
- else => |err| return err,
- }
- if (is_prefix(preopen_path[0..preopen_len], path)) {
- dirfd.* = fd;
- prefix.* = preopen_len;
- return ESUCCESS;
- }
- std.mem.set(u8, &preopen_path, 0);
- fd += 1;
- }
-
- return ENOTCAPABLE;
-}
-
pub const PreopenType = enum {
Dir,
};
@@ -86,50 +42,62 @@ pub const Preopen = struct {
}
};
-pub const GetPreopenError = std.os.UnexpectedError || mem.Allocator.Error;
-
-pub fn getPreopens(allocator: *mem.Allocator) GetPreopenError![]Preopen {
- var preopens = std.ArrayList(Preopen).init(allocator);
- errdefer freePreopens(allocator, preopens);
- var fd: fd_t = 3; // start fd has to be beyond stdio fds
-
- while (true) {
- var buf: prestat_t = undefined;
- switch (fd_prestat_get(fd, &buf)) {
- ESUCCESS => {},
- ENOTSUP => {
- // not a preopen, so keep going
- continue;
- },
- EBADF => {
- // OK, no more fds available
- break;
- },
- else => |err| return std.os.unexpectedErrno(err),
- }
- const preopen_len = buf.u.dir.pr_name_len;
- const path_buf = try allocator.alloc(u8, preopen_len);
- mem.set(u8, path_buf, 0);
- switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
- ESUCCESS => {},
- else => |err| return std.os.unexpectedErrno(err),
- }
- const preopen = Preopen.newDir(fd, path_buf);
- try preopens.append(preopen);
- fd += 1;
+pub const PreopenList = struct {
+ const InnerList = std.ArrayList(Preopen);
+
+ buffer: InnerList,
+
+ const Self = @This();
+ pub const Error = std.os.UnexpectedError || Allocator.Error;
+
+ pub fn init(allocator: *Allocator) Self {
+ return Self{ .buffer = InnerList.init(allocator) };
}
- return preopens.toOwnedSlice();
-}
+ pub fn deinit(pm: Self) void {
+ for (pm.buffer.items) |preopen| {
+ switch (preopen.@"type") {
+ PreopenType.Dir => |path| pm.buffer.allocator.free(path),
+ }
+ }
+ pm.buffer.deinit();
+ }
-pub fn freePreopens(allocator: *mem.Allocator, preopens: std.ArrayList(Preopen)) void {
- for (preopens.items) |preopen| {
- switch (preopen.@"type") {
- PreopenType.Dir => |path| allocator.free(path),
+ pub fn populate(self: *Self) Error!void {
+ errdefer self.deinit();
+ var fd: fd_t = 3; // start fd has to be beyond stdio fds
+
+ while (true) {
+ var buf: prestat_t = undefined;
+ switch (fd_prestat_get(fd, &buf)) {
+ ESUCCESS => {},
+ ENOTSUP => {
+ // not a preopen, so keep going
+ continue;
+ },
+ EBADF => {
+ // OK, no more fds available
+ break;
+ },
+ else => |err| return std.os.unexpectedErrno(err),
+ }
+ const preopen_len = buf.u.dir.pr_name_len;
+ const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
+ mem.set(u8, path_buf, 0);
+ switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
+ ESUCCESS => {},
+ else => |err| return std.os.unexpectedErrno(err),
+ }
+ const preopen = Preopen.newDir(fd, path_buf);
+ try self.buffer.append(preopen);
+ fd += 1;
}
}
- preopens.deinit();
-}
+
+ pub fn asSlice(self: *const Self) []const Preopen {
+ return self.buffer.items;
+ }
+};
pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
lib/std/os.zig
@@ -869,26 +869,6 @@ pub fn open(file_path: []const u8, flags: u32, perm: mode_t) OpenError!fd_t {
return openZ(&file_path_c, flags, perm);
}
-pub fn openWasi(file_path: []const u8, oflags: wasi.oflags_t, fdflags: wasi.fdflags_t, rights: wasi.rights_t) OpenError!fd_t {
- var dirfd: fd_t = undefined;
- var prefix: usize = undefined;
-
- switch (wasi.resolve_preopen(file_path, &dirfd, &prefix)) {
- 0 => {},
- else => |err| return unexpectedErrno(err),
- }
-
- const rel_path = file_path[prefix + 1 ..];
- var fd: fd_t = undefined;
- switch (wasi.path_open(dirfd, 0x0, rel_path.ptr, rel_path.len, oflags, rights, 0x0, fdflags, &fd)) {
- 0 => {},
- // TODO map errors
- else => |err| return unexpectedErrno(err),
- }
-
- return fd;
-}
-
pub const openC = @compileError("deprecated: renamed to openZ");
/// Open and possibly create a file. Keeps trying if it gets interrupted.