| ... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
| 2 | // * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx | 2 | // * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx |
| 3 | // * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx | 3 | // * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx |
| 4 | const std = @import("std"); | 4 | const std = @import("std"); |
| | 5 | const mem = std.mem; |
| 5 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 6 | | 7 | |
| 7 | pub usingnamespace @import("bits.zig"); | 8 | pub usingnamespace @import("bits.zig"); |
| ... | @@ -65,6 +66,71 @@ pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t { | ... | @@ -65,6 +66,71 @@ pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t { |
| 65 | return ENOTCAPABLE; | 66 | return ENOTCAPABLE; |
| 66 | } | 67 | } |
| 67 | | 68 | |
| | 69 | pub const PreopenType = enum { |
| | 70 | Dir, |
| | 71 | }; |
| | 72 | |
| | 73 | pub const Preopen = struct { |
| | 74 | fd: fd_t, |
| | 75 | @"type": union(PreopenType) { |
| | 76 | Dir: []const u8, |
| | 77 | }, |
| | 78 | |
| | 79 | const Self = @This(); |
| | 80 | |
| | 81 | pub fn newDir(fd: fd_t, path: []const u8) Self { |
| | 82 | return Self{ |
| | 83 | .fd = fd, |
| | 84 | .@"type" = .{ .Dir = path }, |
| | 85 | }; |
| | 86 | } |
| | 87 | }; |
| | 88 | |
| | 89 | pub const GetPreopenError = std.os.UnexpectedError || mem.Allocator.Error; |
| | 90 | |
| | 91 | pub 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; |
| | 120 | } |
| | 121 | |
| | 122 | return preopens.toOwnedSlice(); |
| | 123 | } |
| | 124 | |
| | 125 | pub 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), |
| | 129 | } |
| | 130 | } |
| | 131 | preopens.deinit(); |
| | 132 | } |
| | 133 | |
| 68 | pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t; | 134 | pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t; |
| 69 | pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t; | 135 | pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t; |
| 70 | | 136 | |