authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-23 22:23:20-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-06-23 22:23:20-04:00
loga1a1f94a0dbd4e4975577357987c786cacc9e6a2
tree9472a5c2fbbe2ab97ef56c8bcaa9b9b4044c29dc
parent0de35af98b3404f0cf7cd9497f661239d197bbbf
parent5fed725e0a4e8d2617f2b8fc98191103d1ebd3ea
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #5681 from kubkon/refactor-wasi-preopens

[libstd]: refactor std.fs.wasi.PreopenList.find()

3 files changed, 43 insertions(+), 37 deletions(-)

doc/langref.html.in+1-1
......@@ -9738,7 +9738,7 @@ pub fn main() !void {
97389738}
97399739 {#code_end#}
97409740 <pre><code>$ wasmtime --dir=. preopens.wasm
97410: { .fd = 3, .Dir = '.' }
97410: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }
97429742</code></pre>
97439743 {#header_close#}
97449744 {#header_close#}
lib/std/fs/wasi.zig+41-35
......@@ -5,13 +5,39 @@ const Allocator = mem.Allocator;
55
66usingnamespace std.os.wasi;
77
8/// Type of WASI preopen.
8/// Type-tag of WASI preopen.
99///
1010/// WASI currently offers only `Dir` as a valid preopen resource.
11pub const PreopenType = enum {
11pub const PreopenTypeTag = enum {
1212 Dir,
1313};
1414
15/// Type of WASI preopen.
16///
17/// WASI currently offers only `Dir` as a valid preopen resource.
18pub const PreopenType = union(PreopenTypeTag) {
19 /// Preopened directory type.
20 Dir: []const u8,
21
22 const Self = @This();
23
24 pub fn eql(self: Self, other: PreopenType) bool {
25 if (!mem.eql(u8, @tagName(self), @tagName(other))) return false;
26
27 switch (self) {
28 PreopenTypeTag.Dir => |this_path| return mem.eql(u8, this_path, other.Dir),
29 }
30 }
31
32 pub fn format(self: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: var) !void {
33 try out_stream.print("PreopenType{{ ", .{});
34 switch (self) {
35 PreopenType.Dir => |path| try out_stream.print(".Dir = '{}'", .{path}),
36 }
37 return out_stream.print(" }}", .{});
38 }
39};
40
1541/// WASI preopen struct. This struct consists of a WASI file descriptor
1642/// and type of WASI preopen. It can be obtained directly from the WASI
1743/// runtime using `PreopenList.populate()` method.
......@@ -20,29 +46,15 @@ pub const Preopen = struct {
2046 fd: fd_t,
2147
2248 /// Type of the preopen.
23 @"type": union(PreopenType) {
24 /// Path to a preopened directory.
25 Dir: []const u8,
26 },
49 @"type": PreopenType,
2750
28 const Self = @This();
29
30 /// Construct new `Preopen` instance of type `PreopenType.Dir` from
31 /// WASI file descriptor and WASI path.
32 pub fn newDir(fd: fd_t, path: []const u8) Self {
33 return Self{
51 /// Construct new `Preopen` instance.
52 pub fn new(fd: fd_t, preopen_type: PreopenType) Preopen {
53 return Preopen{
3454 .fd = fd,
35 .@"type" = .{ .Dir = path },
55 .@"type" = preopen_type,
3656 };
3757 }
38
39 pub fn format(self: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: var) !void {
40 try out_stream.print("{{ .fd = {}, ", .{self.fd});
41 switch (self.@"type") {
42 PreopenType.Dir => |path| try out_stream.print(".Dir = '{}'", .{path}),
43 }
44 return out_stream.print(" }}", .{});
45 }
4658};
4759
4860/// Dynamically-sized array list of WASI preopens. This struct is a
......@@ -113,24 +125,18 @@ pub const PreopenList = struct {
113125 ESUCCESS => {},
114126 else => |err| return os.unexpectedErrno(err),
115127 }
116 const preopen = Preopen.newDir(fd, path_buf);
128 const preopen = Preopen.new(fd, PreopenType{ .Dir = path_buf });
117129 try self.buffer.append(preopen);
118130 fd += 1;
119131 }
120132 }
121133
122 /// Find preopen by path. If the preopen exists, return it.
134 /// Find preopen by type. If the preopen exists, return it.
123135 /// Otherwise, return `null`.
124 ///
125 /// TODO make the function more generic by searching by `PreopenType` union. This will
126 /// be needed in the future when WASI extends its capabilities to resources
127 /// other than preopened directories.
128 pub fn find(self: Self, path: []const u8) ?*const Preopen {
129 for (self.buffer.items) |preopen| {
130 switch (preopen.@"type") {
131 PreopenType.Dir => |preopen_path| {
132 if (mem.eql(u8, path, preopen_path)) return &preopen;
133 },
136 pub fn find(self: Self, preopen_type: PreopenType) ?*const Preopen {
137 for (self.buffer.items) |*preopen| {
138 if (preopen.@"type".eql(preopen_type)) {
139 return preopen;
134140 }
135141 }
136142 return null;
......@@ -156,7 +162,7 @@ test "extracting WASI preopens" {
156162 try preopens.populate();
157163
158164 std.testing.expectEqual(@as(usize, 1), preopens.asSlice().len);
159 const preopen = preopens.find(".") orelse unreachable;
160 std.testing.expect(std.mem.eql(u8, ".", preopen.@"type".Dir));
165 const preopen = preopens.find(PreopenType{ .Dir = "." }) orelse unreachable;
166 std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "." }));
161167 std.testing.expectEqual(@as(usize, 3), preopen.fd);
162168}
lib/std/testing.zig+1-1
......@@ -215,7 +215,7 @@ fn getCwdOrWasiPreopen() std.fs.Dir {
215215 defer preopens.deinit();
216216 preopens.populate() catch
217217 @panic("unable to make tmp dir for testing: unable to populate preopens");
218 const preopen = preopens.find(".") orelse
218 const preopen = preopens.find(std.fs.wasi.PreopenType{ .Dir = "." }) orelse
219219 @panic("unable to make tmp dir for testing: didn't find '.' in the preopens");
220220
221221 return std.fs.Dir{ .fd = preopen.fd };