authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 17:05:30+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 17:05:30+02:00
log07a968b3444c1db036d605ed8a25bc128110b646
treed1bb0685e00ada41138961791fc5e15445cfec5a
parent558bb24601c6de5f05cded4e99b795e85bb3b8e6

Add docs


2 files changed, 66 insertions(+), 15 deletions(-)

lib/std/fs.zig+32-14
...@@ -592,19 +592,27 @@ pub const Dir = struct {...@@ -592,19 +592,27 @@ pub const Dir = struct {
592 return self.openFileZ(&path_c, flags);592 return self.openFileZ(&path_c, flags);
593 }593 }
594594
595 fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {595 /// Save as `openFile` but WASI only.
596 var fdflags: wasi.fdflag_t = 0x0;596 pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
597 var rights: wasi.rights_t = 0x0;597 const w = os.wasi;
598 var fdflags: w.fdflag_t = 0x0;
599 var rights: w.rights_t = 0x0;
598 if (flags.read) {600 if (flags.read) {
599 rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET;601 rights |= w.FD_READ | w.FD_TELL | w.FD_FILESTAT_GET;
600 }602 }
601 if (flags.write) {603 if (flags.write) {
602 fdflags |= wasi.FDFLAG_APPEND;604 fdflags |= w.FDFLAG_APPEND;
603 rights |= wasi.FD_WRITE | wasi.FD_DATASYNC | wasi.FD_SEEK | wasi.FD_FDSTAT_SET_FLAGS | wasi.FD_SYNC | wasi.FD_ALLOCATE | wasi.FD_ADVISE | wasi.FD_FILESTAT_SET_TIMES | wasi.FD_FILESTAT_SET_SIZE;605 rights |= w.FD_WRITE |
606 w.FD_DATASYNC |
607 w.FD_SEEK |
608 w.FD_FDSTAT_SET_FLAGS |
609 w.FD_SYNC |
610 w.FD_ALLOCATE |
611 w.FD_ADVISE |
612 w.FD_FILESTAT_SET_TIMES |
613 w.FD_FILESTAT_SET_SIZE;
604 }614 }
605
606 const fd = try wasi.openat(self.fd, sub_path, 0x0, fdflags, rights);615 const fd = try wasi.openat(self.fd, sub_path, 0x0, fdflags, rights);
607
608 return File{ .handle = fd };616 return File{ .handle = fd };
609 }617 }
610618
...@@ -700,17 +708,27 @@ pub const Dir = struct {...@@ -700,17 +708,27 @@ pub const Dir = struct {
700708
701 pub const createFileC = @compileError("deprecated: renamed to createFileZ");709 pub const createFileC = @compileError("deprecated: renamed to createFileZ");
702710
703 fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {711 /// Same as `createFile` but WASI only.
704 var oflags: wasi.oflags_t = wasi.O_CREAT;712 pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
705 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;713 const w = os.wasi;
714 var oflags = w.O_CREAT;
715 var rights = w.RIGHT_FD_WRITE |
716 w.RIGHT_FD_DATASYNC |
717 w.RIGHT_FD_SEEK |
718 w.RIGHT_FD_FDSTAT_SET_FLAGS |
719 w.RIGHT_FD_SYNC |
720 w.RIGHT_FD_ALLOCATE |
721 w.RIGHT_FD_ADVISE |
722 w.RIGHT_FD_FILESTAT_SET_TIMES |
723 w.RIGHT_FD_FILESTAT_SET_SIZE;
706 if (flags.read) {724 if (flags.read) {
707 rights |= wasi.RIGHT_FD_READ | wasi.RIGHT_FD_TELL | wasi.RIGHT_FD_FILESTAT_GET;725 rights |= w.RIGHT_FD_READ | w.RIGHT_FD_TELL | w.RIGHT_FD_FILESTAT_GET;
708 }726 }
709 if (flags.truncate) {727 if (flags.truncate) {
710 oflags |= wasi.O_TRUNC;728 oflags |= w.O_TRUNC;
711 }729 }
712 if (flags.exclusive) {730 if (flags.exclusive) {
713 oflags |= wasi.O_EXCL;731 oflags |= w.O_EXCL;
714 }732 }
715 const fd = try wasi.openat(self.fd, sub_path, oflags, 0x0, rights);733 const fd = try wasi.openat(self.fd, sub_path, oflags, 0x0, rights);
716 return File{ .handle = fd };734 return File{ .handle = fd };
lib/std/fs/wasi.zig+34-1
...@@ -5,18 +5,30 @@ const Allocator = mem.Allocator;...@@ -5,18 +5,30 @@ const Allocator = mem.Allocator;
55
6usingnamespace std.os.wasi;6usingnamespace std.os.wasi;
77
8/// Type of WASI preopen.
9///
10/// WASI currently offers only `Dir` as a valid preopen resource.
8pub const PreopenType = enum {11pub const PreopenType = enum {
9 Dir,12 Dir,
10};13};
1114
15/// WASI preopen struct. This struct consists of a WASI file descriptor
16/// and type of WASI preopen. It can be obtained directly from the WASI
17/// runtime using `PreopenList.populate()` method.
12pub const Preopen = struct {18pub const Preopen = struct {
19 /// WASI file descriptor.
13 fd: fd_t,20 fd: fd_t,
21
22 /// Type of the preopen.
14 @"type": union(PreopenType) {23 @"type": union(PreopenType) {
24 /// Path to a preopened directory.
15 Dir: []const u8,25 Dir: []const u8,
16 },26 },
1727
18 const Self = @This();28 const Self = @This();
1929
30 /// Construct new `Preopen` instance of type `PreopenType.Dir` from
31 /// WASI file descriptor and WASI path.
20 pub fn newDir(fd: fd_t, path: []const u8) Self {32 pub fn newDir(fd: fd_t, path: []const u8) Self {
21 return Self{33 return Self{
22 .fd = fd,34 .fd = fd,
...@@ -25,18 +37,29 @@ pub const Preopen = struct {...@@ -25,18 +37,29 @@ pub const Preopen = struct {
25 }37 }
26};38};
2739
40/// Dynamically-sized array list of WASI preopens. This struct is a
41/// convenience wrapper for issuing `std.os.wasi.fd_prestat_get` and
42/// `std.os.wasi.fd_prestat_dir_name` syscalls to the WASI runtime, and
43/// collecting the returned preopens.
44///
45/// This struct is intended to be used in any WASI program which intends
46/// to use the capabilities as passed on by the user of the runtime.
28pub const PreopenList = struct {47pub const PreopenList = struct {
29 const InnerList = std.ArrayList(Preopen);48 const InnerList = std.ArrayList(Preopen);
3049
50 /// Internal dynamically-sized buffer for storing the gathered preopens.
31 buffer: InnerList,51 buffer: InnerList,
3252
33 const Self = @This();53 const Self = @This();
54
34 pub const Error = os.UnexpectedError || Allocator.Error;55 pub const Error = os.UnexpectedError || Allocator.Error;
3556
57 /// Deinitialize with `deinit`.
36 pub fn init(allocator: *Allocator) Self {58 pub fn init(allocator: *Allocator) Self {
37 return Self{ .buffer = InnerList.init(allocator) };59 return Self{ .buffer = InnerList.init(allocator) };
38 }60 }
3961
62 /// Release all allocated memory.
40 pub fn deinit(pm: Self) void {63 pub fn deinit(pm: Self) void {
41 for (pm.buffer.items) |preopen| {64 for (pm.buffer.items) |preopen| {
42 switch (preopen.@"type") {65 switch (preopen.@"type") {
...@@ -46,6 +69,8 @@ pub const PreopenList = struct {...@@ -46,6 +69,8 @@ pub const PreopenList = struct {
46 pm.buffer.deinit();69 pm.buffer.deinit();
47 }70 }
4871
72 /// Populate the list with the preopens by issuing `std.os.wasi.fd_prestat_get`
73 /// and `std.os.wasi.fd_prestat_dir_name` syscalls to the runtime.
49 pub fn populate(self: *Self) Error!void {74 pub fn populate(self: *Self) Error!void {
50 errdefer self.deinit();75 errdefer self.deinit();
51 var fd: fd_t = 3; // start fd has to be beyond stdio fds76 var fd: fd_t = 3; // start fd has to be beyond stdio fds
...@@ -77,6 +102,12 @@ pub const PreopenList = struct {...@@ -77,6 +102,12 @@ pub const PreopenList = struct {
77 }102 }
78 }103 }
79104
105 /// Find preopen by path. If the preopen exists, return it.
106 /// Otherwise, return `null`.
107 ///
108 /// TODO make the function more generic by searching by `PreopenType` union. This will
109 /// be needed in the future when WASI extends its capabilities to resources
110 /// other than preopened directories.
80 pub fn find(self: *const Self, path: []const u8) ?*const Preopen {111 pub fn find(self: *const Self, path: []const u8) ?*const Preopen {
81 for (self.buffer.items) |preopen| {112 for (self.buffer.items) |preopen| {
82 switch (preopen.@"type") {113 switch (preopen.@"type") {
...@@ -88,12 +119,14 @@ pub const PreopenList = struct {...@@ -88,12 +119,14 @@ pub const PreopenList = struct {
88 return null;119 return null;
89 }120 }
90121
122 /// Return the inner buffer as read-only slice.
91 pub fn asSlice(self: *const Self) []const Preopen {123 pub fn asSlice(self: *const Self) []const Preopen {
92 return self.buffer.items;124 return self.buffer.items;
93 }125 }
94};126};
95127
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 {128/// Convenience wrapper for `std.os.wasi.path_open` syscall.
129pub fn openat(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, rights: rights_t) os.OpenError!fd_t {
97 var fd: fd_t = undefined;130 var fd: fd_t = undefined;
98 switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {131 switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
99 0 => {},132 0 => {},