authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-04 21:20:00+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 15:08:52+02:00
logdd238352a4d3a9f02ff62d32cd109adabee30b66
treee5fbf7f16309dba07de5e602f339143d5741ea73
parentfc77e393fdbaf874ab22d528ba2bc3d63836b439

Encapsulate getPreopens inside PreopenList


2 files changed, 52 insertions(+), 104 deletions(-)

lib/std/os.zig-20
......@@ -869,26 +869,6 @@ pub fn open(file_path: []const u8, flags: u32, perm: mode_t) OpenError!fd_t {
869869 return openZ(&file_path_c, flags, perm);
870870}
871871
872pub fn openWasi(file_path: []const u8, oflags: wasi.oflags_t, fdflags: wasi.fdflags_t, rights: wasi.rights_t) OpenError!fd_t {
873 var dirfd: fd_t = undefined;
874 var prefix: usize = undefined;
875
876 switch (wasi.resolve_preopen(file_path, &dirfd, &prefix)) {
877 0 => {},
878 else => |err| return unexpectedErrno(err),
879 }
880
881 const rel_path = file_path[prefix + 1 ..];
882 var fd: fd_t = undefined;
883 switch (wasi.path_open(dirfd, 0x0, rel_path.ptr, rel_path.len, oflags, rights, 0x0, fdflags, &fd)) {
884 0 => {},
885 // TODO map errors
886 else => |err| return unexpectedErrno(err),
887 }
888
889 return fd;
890}
891
892872pub const openC = @compileError("deprecated: renamed to openZ");
893873
894874/// Open and possibly create a file. Keeps trying if it gets interrupted.
lib/std/os/wasi.zig+52-84
......@@ -4,6 +4,7 @@
44const std = @import("std");
55const mem = std.mem;
66const assert = std.debug.assert;
7const Allocator = mem.Allocator;
78
89pub usingnamespace @import("bits.zig");
910
......@@ -21,51 +22,6 @@ comptime {
2122pub const iovec_t = iovec;
2223pub const ciovec_t = iovec_const;
2324
24fn is_prefix(preopen: []const u8, path: []const u8) bool {
25 if (preopen.len > path.len) {
26 return false;
27 }
28 var i: usize = 0;
29 while (i < preopen.len) {
30 std.debug.warn("{} == {}", .{ preopen[i], path[i] });
31 if (preopen[i] != path[i]) {
32 return false;
33 }
34 i += 1;
35 }
36 return true;
37}
38
39pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t {
40 var fd: fd_t = 3; // start fd has to be beyond stdio fds
41 var preopen_path = [_]u8{0} ** PATH_MAX;
42
43 while (true) {
44 var buf: prestat_t = undefined;
45 switch (fd_prestat_get(fd, &buf)) {
46 ESUCCESS => {},
47 EBADF => {
48 break;
49 },
50 else => |err| return err,
51 }
52 const preopen_len = buf.u.dir.pr_name_len;
53 switch (fd_prestat_dir_name(fd, &preopen_path, preopen_len)) {
54 ESUCCESS => {},
55 else => |err| return err,
56 }
57 if (is_prefix(preopen_path[0..preopen_len], path)) {
58 dirfd.* = fd;
59 prefix.* = preopen_len;
60 return ESUCCESS;
61 }
62 std.mem.set(u8, &preopen_path, 0);
63 fd += 1;
64 }
65
66 return ENOTCAPABLE;
67}
68
6925pub const PreopenType = enum {
7026 Dir,
7127};
......@@ -86,50 +42,62 @@ pub const Preopen = struct {
8642 }
8743};
8844
89pub const GetPreopenError = std.os.UnexpectedError || mem.Allocator.Error;
90
91pub fn getPreopens(allocator: *mem.Allocator) GetPreopenError![]Preopen {
92 var preopens = std.ArrayList(Preopen).init(allocator);
93 errdefer freePreopens(allocator, preopens);
94 var fd: fd_t = 3; // start fd has to be beyond stdio fds
95
96 while (true) {
97 var buf: prestat_t = undefined;
98 switch (fd_prestat_get(fd, &buf)) {
99 ESUCCESS => {},
100 ENOTSUP => {
101 // not a preopen, so keep going
102 continue;
103 },
104 EBADF => {
105 // OK, no more fds available
106 break;
107 },
108 else => |err| return std.os.unexpectedErrno(err),
109 }
110 const preopen_len = buf.u.dir.pr_name_len;
111 const path_buf = try allocator.alloc(u8, preopen_len);
112 mem.set(u8, path_buf, 0);
113 switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
114 ESUCCESS => {},
115 else => |err| return std.os.unexpectedErrno(err),
116 }
117 const preopen = Preopen.newDir(fd, path_buf);
118 try preopens.append(preopen);
119 fd += 1;
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) };
12055 }
12156
122 return preopens.toOwnedSlice();
123}
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 }
12465
125pub fn freePreopens(allocator: *mem.Allocator, preopens: std.ArrayList(Preopen)) void {
126 for (preopens.items) |preopen| {
127 switch (preopen.@"type") {
128 PreopenType.Dir => |path| allocator.free(path),
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;
12994 }
13095 }
131 preopens.deinit();
132}
96
97 pub fn asSlice(self: *const Self) []const Preopen {
98 return self.buffer.items;
99 }
100};
133101
134102pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
135103pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;