authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 15:07:21+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 15:08:52+02:00
log558bb24601c6de5f05cded4e99b795e85bb3b8e6
treec14c072c0421ef1b8253064419732941dd6e6e8b
parentd4c33129cf86441a59079e15fd887711fae8d924

Move preopen and path wasi helpers to std.fs.wasi module

Previously, the path and preopens helpers were prototyped in `std.os.wasi` module, but since they are higher-level abstraction over wasi, they belong in `std.fs.wasi` module.

3 files changed, 106 insertions(+), 104 deletions(-)

lib/std/fs.zig+2-4
......@@ -12,6 +12,7 @@ const is_darwin = std.Target.current.os.tag.isDarwin();
1212
1313pub const path = @import("fs/path.zig");
1414pub const File = @import("fs/file.zig").File;
15pub const wasi = @import("fs/wasi.zig");
1516
1617// TODO audit these APIs with respect to Dir and absolute paths
1718
......@@ -37,7 +38,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
3738/// fit into a UTF-8 encoded array of this length.
3839/// The byte count includes room for a null sentinel byte.
3940pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
40 .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly, .wasi => os.PATH_MAX,
41 .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX,
4142 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
4243 // If it would require 4 UTF-8 bytes, then there would be a surrogate
4344 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
......@@ -700,7 +701,6 @@ pub const Dir = struct {
700701 pub const createFileC = @compileError("deprecated: renamed to createFileZ");
701702
702703 fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
703 const wasi = os.wasi;
704704 var oflags: wasi.oflags_t = wasi.O_CREAT;
705705 var rights: wasi.rights_t = wasi.RIGHT_FD_WRITE | wasi.RIGHT_FD_DATASYNC | wasi.RIGHT_FD_SEEK | wasi.RIGHT_FD_FDSTAT_SET_FLAGS | wasi.RIGHT_FD_SYNC | wasi.RIGHT_FD_ALLOCATE | wasi.RIGHT_FD_ADVISE | wasi.RIGHT_FD_FILESTAT_SET_TIMES | wasi.RIGHT_FD_FILESTAT_SET_SIZE;
706706 if (flags.read) {
......@@ -712,9 +712,7 @@ pub const Dir = struct {
712712 if (flags.exclusive) {
713713 oflags |= wasi.O_EXCL;
714714 }
715
716715 const fd = try wasi.openat(self.fd, sub_path, oflags, 0x0, rights);
717
718716 return File{ .handle = fd };
719717 }
720718
lib/std/fs/wasi.zig created+104
......@@ -0,0 +1,104 @@
1const std = @import("std");
2const os = std.os;
3const mem = std.mem;
4const Allocator = mem.Allocator;
5
6usingnamespace std.os.wasi;
7
8pub const PreopenType = enum {
9 Dir,
10};
11
12pub const Preopen = struct {
13 fd: fd_t,
14 @"type": union(PreopenType) {
15 Dir: []const u8,
16 },
17
18 const Self = @This();
19
20 pub fn newDir(fd: fd_t, path: []const u8) Self {
21 return Self{
22 .fd = fd,
23 .@"type" = .{ .Dir = path },
24 };
25 }
26};
27
28pub const PreopenList = struct {
29 const InnerList = std.ArrayList(Preopen);
30
31 buffer: InnerList,
32
33 const Self = @This();
34 pub const Error = os.UnexpectedError || Allocator.Error;
35
36 pub fn init(allocator: *Allocator) Self {
37 return Self{ .buffer = InnerList.init(allocator) };
38 }
39
40 pub fn deinit(pm: Self) void {
41 for (pm.buffer.items) |preopen| {
42 switch (preopen.@"type") {
43 PreopenType.Dir => |path| pm.buffer.allocator.free(path),
44 }
45 }
46 pm.buffer.deinit();
47 }
48
49 pub fn populate(self: *Self) Error!void {
50 errdefer self.deinit();
51 var fd: fd_t = 3; // start fd has to be beyond stdio fds
52
53 while (true) {
54 var buf: prestat_t = undefined;
55 switch (fd_prestat_get(fd, &buf)) {
56 ESUCCESS => {},
57 ENOTSUP => {
58 // not a preopen, so keep going
59 continue;
60 },
61 EBADF => {
62 // OK, no more fds available
63 break;
64 },
65 else => |err| return os.unexpectedErrno(err),
66 }
67 const preopen_len = buf.u.dir.pr_name_len;
68 const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
69 mem.set(u8, path_buf, 0);
70 switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
71 ESUCCESS => {},
72 else => |err| return os.unexpectedErrno(err),
73 }
74 const preopen = Preopen.newDir(fd, path_buf);
75 try self.buffer.append(preopen);
76 fd += 1;
77 }
78 }
79
80 pub fn find(self: *const Self, path: []const u8) ?*const Preopen {
81 for (self.buffer.items) |preopen| {
82 switch (preopen.@"type") {
83 PreopenType.Dir => |preopen_path| {
84 if (mem.eql(u8, path, preopen_path)) return &preopen;
85 },
86 }
87 }
88 return null;
89 }
90
91 pub fn asSlice(self: *const Self) []const Preopen {
92 return self.buffer.items;
93 }
94};
95
96pub fn openat(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, rights: rights_t) std.os.OpenError!fd_t {
97 var fd: fd_t = undefined;
98 switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
99 0 => {},
100 // TODO map errors
101 else => |err| return std.os.unexpectedErrno(err),
102 }
103 return fd;
104}
lib/std/os/wasi.zig-100
......@@ -2,9 +2,7 @@
22// * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
33// * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx
44const std = @import("std");
5const mem = std.mem;
65const assert = std.debug.assert;
7const Allocator = mem.Allocator;
86
97pub usingnamespace @import("bits.zig");
108
......@@ -22,104 +20,6 @@ comptime {
2220pub const iovec_t = iovec;
2321pub const ciovec_t = iovec_const;
2422
25pub const PreopenType = enum {
26 Dir,
27};
28
29pub const Preopen = struct {
30 fd: fd_t,
31 @"type": union(PreopenType) {
32 Dir: []const u8,
33 },
34
35 const Self = @This();
36
37 pub fn newDir(fd: fd_t, path: []const u8) Self {
38 return Self{
39 .fd = fd,
40 .@"type" = .{ .Dir = path },
41 };
42 }
43};
44
45pub const PreopenList = struct {
46 const InnerList = std.ArrayList(Preopen);
47
48 buffer: InnerList,
49
50 const Self = @This();
51 pub const Error = std.os.UnexpectedError || Allocator.Error;
52
53 pub fn init(allocator: *Allocator) Self {
54 return Self{ .buffer = InnerList.init(allocator) };
55 }
56
57 pub fn deinit(pm: Self) void {
58 for (pm.buffer.items) |preopen| {
59 switch (preopen.@"type") {
60 PreopenType.Dir => |path| pm.buffer.allocator.free(path),
61 }
62 }
63 pm.buffer.deinit();
64 }
65
66 pub fn populate(self: *Self) Error!void {
67 errdefer self.deinit();
68 var fd: fd_t = 3; // start fd has to be beyond stdio fds
69
70 while (true) {
71 var buf: prestat_t = undefined;
72 switch (fd_prestat_get(fd, &buf)) {
73 ESUCCESS => {},
74 ENOTSUP => {
75 // not a preopen, so keep going
76 continue;
77 },
78 EBADF => {
79 // OK, no more fds available
80 break;
81 },
82 else => |err| return std.os.unexpectedErrno(err),
83 }
84 const preopen_len = buf.u.dir.pr_name_len;
85 const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
86 mem.set(u8, path_buf, 0);
87 switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
88 ESUCCESS => {},
89 else => |err| return std.os.unexpectedErrno(err),
90 }
91 const preopen = Preopen.newDir(fd, path_buf);
92 try self.buffer.append(preopen);
93 fd += 1;
94 }
95 }
96
97 pub fn find(self: *const Self, path: []const u8) ?*const Preopen {
98 for (self.buffer.items) |preopen| {
99 switch (preopen.@"type") {
100 PreopenType.Dir => |preopen_path| {
101 if (mem.eql(u8, path, preopen_path)) return &preopen;
102 },
103 }
104 }
105 return null;
106 }
107
108 pub fn asSlice(self: *const Self) []const Preopen {
109 return self.buffer.items;
110 }
111};
112
113pub fn openat(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, rights: rights_t) std.os.OpenError!fd_t {
114 var fd: fd_t = undefined;
115 switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
116 0 => {},
117 // TODO map errors
118 else => |err| return std.os.unexpectedErrno(err),
119 }
120 return fd;
121}
122
12323pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
12424pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
12525