Commit 558bb24601

Jakub Konka <kubkon@jakubkonka.com>
2020-05-05 15:07:21
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.
1 parent d4c3312
Changed files (3)
lib/std/fs/wasi.zig
@@ -0,0 +1,104 @@
+const std = @import("std");
+const os = std.os;
+const mem = std.mem;
+const Allocator = mem.Allocator;
+
+usingnamespace std.os.wasi;
+
+pub const PreopenType = enum {
+    Dir,
+};
+
+pub const Preopen = struct {
+    fd: fd_t,
+    @"type": union(PreopenType) {
+        Dir: []const u8,
+    },
+
+    const Self = @This();
+
+    pub fn newDir(fd: fd_t, path: []const u8) Self {
+        return Self{
+            .fd = fd,
+            .@"type" = .{ .Dir = path },
+        };
+    }
+};
+
+pub const PreopenList = struct {
+    const InnerList = std.ArrayList(Preopen);
+
+    buffer: InnerList,
+
+    const Self = @This();
+    pub const Error = os.UnexpectedError || Allocator.Error;
+
+    pub fn init(allocator: *Allocator) Self {
+        return Self{ .buffer = InnerList.init(allocator) };
+    }
+
+    pub fn deinit(pm: Self) void {
+        for (pm.buffer.items) |preopen| {
+            switch (preopen.@"type") {
+                PreopenType.Dir => |path| pm.buffer.allocator.free(path),
+            }
+        }
+        pm.buffer.deinit();
+    }
+
+    pub fn populate(self: *Self) Error!void {
+        errdefer self.deinit();
+        var fd: fd_t = 3; // start fd has to be beyond stdio fds
+
+        while (true) {
+            var buf: prestat_t = undefined;
+            switch (fd_prestat_get(fd, &buf)) {
+                ESUCCESS => {},
+                ENOTSUP => {
+                    // not a preopen, so keep going
+                    continue;
+                },
+                EBADF => {
+                    // OK, no more fds available
+                    break;
+                },
+                else => |err| return os.unexpectedErrno(err),
+            }
+            const preopen_len = buf.u.dir.pr_name_len;
+            const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
+            mem.set(u8, path_buf, 0);
+            switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
+                ESUCCESS => {},
+                else => |err| return os.unexpectedErrno(err),
+            }
+            const preopen = Preopen.newDir(fd, path_buf);
+            try self.buffer.append(preopen);
+            fd += 1;
+        }
+    }
+
+    pub fn find(self: *const Self, path: []const u8) ?*const Preopen {
+        for (self.buffer.items) |preopen| {
+            switch (preopen.@"type") {
+                PreopenType.Dir => |preopen_path| {
+                    if (mem.eql(u8, path, preopen_path)) return &preopen;
+                },
+            }
+        }
+        return null;
+    }
+
+    pub fn asSlice(self: *const Self) []const Preopen {
+        return self.buffer.items;
+    }
+};
+
+pub fn openat(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, rights: rights_t) std.os.OpenError!fd_t {
+    var fd: fd_t = undefined;
+    switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
+        0 => {},
+        // TODO map errors
+        else => |err| return std.os.unexpectedErrno(err),
+    }
+    return fd;
+}
lib/std/os/wasi.zig
@@ -2,9 +2,7 @@
 // * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
 // * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx
 const std = @import("std");
-const mem = std.mem;
 const assert = std.debug.assert;
-const Allocator = mem.Allocator;
 
 pub usingnamespace @import("bits.zig");
 
@@ -22,104 +20,6 @@ comptime {
 pub const iovec_t = iovec;
 pub const ciovec_t = iovec_const;
 
-pub const PreopenType = enum {
-    Dir,
-};
-
-pub const Preopen = struct {
-    fd: fd_t,
-    @"type": union(PreopenType) {
-        Dir: []const u8,
-    },
-
-    const Self = @This();
-
-    pub fn newDir(fd: fd_t, path: []const u8) Self {
-        return Self{
-            .fd = fd,
-            .@"type" = .{ .Dir = path },
-        };
-    }
-};
-
-pub const PreopenList = struct {
-    const InnerList = std.ArrayList(Preopen);
-
-    buffer: InnerList,
-
-    const Self = @This();
-    pub const Error = std.os.UnexpectedError || Allocator.Error;
-
-    pub fn init(allocator: *Allocator) Self {
-        return Self{ .buffer = InnerList.init(allocator) };
-    }
-
-    pub fn deinit(pm: Self) void {
-        for (pm.buffer.items) |preopen| {
-            switch (preopen.@"type") {
-                PreopenType.Dir => |path| pm.buffer.allocator.free(path),
-            }
-        }
-        pm.buffer.deinit();
-    }
-
-    pub fn populate(self: *Self) Error!void {
-        errdefer self.deinit();
-        var fd: fd_t = 3; // start fd has to be beyond stdio fds
-
-        while (true) {
-            var buf: prestat_t = undefined;
-            switch (fd_prestat_get(fd, &buf)) {
-                ESUCCESS => {},
-                ENOTSUP => {
-                    // not a preopen, so keep going
-                    continue;
-                },
-                EBADF => {
-                    // OK, no more fds available
-                    break;
-                },
-                else => |err| return std.os.unexpectedErrno(err),
-            }
-            const preopen_len = buf.u.dir.pr_name_len;
-            const path_buf = try self.buffer.allocator.alloc(u8, preopen_len);
-            mem.set(u8, path_buf, 0);
-            switch (fd_prestat_dir_name(fd, path_buf.ptr, preopen_len)) {
-                ESUCCESS => {},
-                else => |err| return std.os.unexpectedErrno(err),
-            }
-            const preopen = Preopen.newDir(fd, path_buf);
-            try self.buffer.append(preopen);
-            fd += 1;
-        }
-    }
-
-    pub fn find(self: *const Self, path: []const u8) ?*const Preopen {
-        for (self.buffer.items) |preopen| {
-            switch (preopen.@"type") {
-                PreopenType.Dir => |preopen_path| {
-                    if (mem.eql(u8, path, preopen_path)) return &preopen;
-                },
-            }
-        }
-        return null;
-    }
-
-    pub fn asSlice(self: *const Self) []const Preopen {
-        return self.buffer.items;
-    }
-};
-
-pub fn openat(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, rights: rights_t) std.os.OpenError!fd_t {
-    var fd: fd_t = undefined;
-    switch (path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
-        0 => {},
-        // TODO map errors
-        else => |err| return std.os.unexpectedErrno(err),
-    }
-    return fd;
-}
-
 pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
 pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
 
lib/std/fs.zig
@@ -12,6 +12,7 @@ const is_darwin = std.Target.current.os.tag.isDarwin();
 
 pub const path = @import("fs/path.zig");
 pub const File = @import("fs/file.zig").File;
+pub const wasi = @import("fs/wasi.zig");
 
 // TODO audit these APIs with respect to Dir and absolute paths
 
@@ -37,7 +38,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
 /// fit into a UTF-8 encoded array of this length.
 /// The byte count includes room for a null sentinel byte.
 pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
-    .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly, .wasi => os.PATH_MAX,
+    .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX,
     // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
     // If it would require 4 UTF-8 bytes, then there would be a surrogate
     // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@@ -700,7 +701,6 @@ pub const Dir = struct {
     pub const createFileC = @compileError("deprecated: renamed to createFileZ");
 
     fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
-        const wasi = os.wasi;
         var oflags: wasi.oflags_t = wasi.O_CREAT;
         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;
         if (flags.read) {
@@ -712,9 +712,7 @@ pub const Dir = struct {
         if (flags.exclusive) {
             oflags |= wasi.O_EXCL;
         }
-
         const fd = try wasi.openat(self.fd, sub_path, oflags, 0x0, rights);
-
         return File{ .handle = fd };
     }