authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-04-30 18:06:15+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 15:08:52+02:00
logd7ca220121ade4031f09e6a7279fd08b617ee2c0
treef8897ead135882e2c66c8eb56458f4069ceb9857
parentf127dee47424f4c87a4ed5026a2d5be5cce7a135

Start drafting out openZ


3 files changed, 71 insertions(+), 0 deletions(-)

lib/std/os.zig+24
...@@ -879,6 +879,30 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t...@@ -879,6 +879,30 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t
879 return openW(file_path_w.span(), flags, perm);879 return openW(file_path_w.span(), flags, perm);
880 }880 }
881 while (true) {881 while (true) {
882 if (builtin.os.tag == .wasi and !builtin.link_libc) {
883 var dirfd: fd_t = undefined;
884 var prefix: usize = undefined;
885 const path = mem.span(file_path);
886
887 switch (wasi.resolve_preopen(path, &dirfd, &prefix)) {
888 0 => {},
889 else => |err| return unexpectedErrno(err),
890 }
891
892 const rel_path = path[prefix + 1 ..];
893 // TODO map flags to wasi.oflag_t
894 // TODO call wasi.fd_fdstat_get to verify rights
895 // TODO adjust all flags to path_open
896 var fd: fd_t = undefined;
897
898 switch (wasi.path_open(dirfd, 0x0, rel_path.ptr, rel_path.len, wasi.O_CREAT, 0x0, 0x0, 0x0, &fd)) {
899 0 => {},
900 else => |err| return unexpectedErrno(err),
901 }
902
903 return fd;
904 }
905
882 const rc = system.open(file_path, flags, perm);906 const rc = system.open(file_path, flags, perm);
883 switch (errno(rc)) {907 switch (errno(rc)) {
884 0 => return @intCast(fd_t, rc),908 0 => return @intCast(fd_t, rc),
lib/std/os/bits/wasi.zig+2
...@@ -12,6 +12,8 @@ pub const timespec = extern struct {...@@ -12,6 +12,8 @@ pub const timespec = extern struct {
12 tv_nsec: isize,12 tv_nsec: isize,
13};13};
1414
15pub const PATH_MAX = 4096; // TODO verify this!
16
15// As defined in the wasi_snapshot_preview1 spec file:17// As defined in the wasi_snapshot_preview1 spec file:
16// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx18// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
17pub const advice_t = u8;19pub const advice_t = u8;
lib/std/os/wasi.zig+45
...@@ -20,6 +20,51 @@ comptime {...@@ -20,6 +20,51 @@ comptime {
20pub const iovec_t = iovec;20pub const iovec_t = iovec;
21pub const ciovec_t = iovec_const;21pub const ciovec_t = iovec_const;
2222
23fn is_prefix(preopen: []const u8, path: []const u8) bool {
24 if (preopen.len > path.len) {
25 return false;
26 }
27 var i: usize = 0;
28 while (i < preopen.len) {
29 std.debug.warn("{} == {}", .{ preopen[i], path[i] });
30 if (preopen[i] != path[i]) {
31 return false;
32 }
33 i += 1;
34 }
35 return true;
36}
37
38pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t {
39 var fd: fd_t = 3; // start fd has to be beyond stdio fds
40 var preopen_path = [_]u8{0} ** PATH_MAX;
41
42 while (true) {
43 var buf: prestat_t = undefined;
44 switch (fd_prestat_get(fd, &buf)) {
45 ESUCCESS => {},
46 EBADF => {
47 break;
48 },
49 else => |err| return err,
50 }
51 const preopen_len = buf.u.dir.pr_name_len;
52 switch (fd_prestat_dir_name(fd, &preopen_path, preopen_len)) {
53 ESUCCESS => {},
54 else => |err| return err,
55 }
56 if (is_prefix(preopen_path[0..preopen_len], path)) {
57 dirfd.* = fd;
58 prefix.* = preopen_len;
59 return ESUCCESS;
60 }
61 std.mem.set(u8, &preopen_path, 0);
62 fd += 1;
63 }
64
65 return ENOTCAPABLE;
66}
67
23pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;68pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
24pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;69pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
2570