Implement std.fs.Dir.openFileWasi

It seems that `std.os.openZ` is too POSIX-specific, so I think it
should not be a point of entry for WASI `open` call. I figure
WASI should be treated as a separate "os" that's _not_ POSIX
especially given the incoming changes in the ephemeral snapshot.
This commit is contained in:
Jakub Konka
2020-05-01 12:33:11 +02:00
parent d7ca220121
commit 8e1cd69717
2 changed files with 79 additions and 25 deletions

View File

@@ -37,7 +37,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 => os.PATH_MAX,
.linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly, .wasi => 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.
@@ -584,10 +584,33 @@ pub const Dir = struct {
const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
return self.openFileW(path_w.span(), flags);
}
if (builtin.os.tag == .wasi) {
return self.openFileWasi(sub_path, flags);
}
const path_c = try os.toPosixPath(sub_path);
return self.openFileZ(&path_c, flags);
}
pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
var fdflags: wasi.fdflag_t = 0x0;
var rights: wasi.rights_t = 0x0;
if (flags.read) {
rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET;
}
if (flags.write) {
fdflags |= wasi.FDFLAG_APPEND;
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;
}
const fd = try os.openatWasi(self.fd, sub_path, 0x0, fdflags, rights);
return File{
.handle = fd,
.io_mode = .blocking,
.async_block_allowed = File.async_block_allowed_no,
};
}
pub const openFileC = @compileError("deprecated: renamed to openFileZ");
/// Same as `openFile` but the path parameter is null-terminated.
@@ -671,12 +694,37 @@ pub const Dir = struct {
const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
return self.createFileW(path_w.span(), flags);
}
if (builtin.os.tag == .wasi) {
return self.createFileWasi(sub_path, flags);
}
const path_c = try os.toPosixPath(sub_path);
return self.createFileZ(&path_c, flags);
}
pub const createFileC = @compileError("deprecated: renamed to createFileZ");
pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
var oflags: wasi.oflags_t = 0x0;
var rights: wasi.rights_t = 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;
if (flags.read) {
rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET;
}
if (flags.truncate) {
oflags |= wasi.O_TRUNC;
}
if (flags.exclusive) {
oflags |= wasi.O_EXCL;
}
const fd = try os.openatWasi(self.fd, sub_path, oflags, 0x0, rights);
return File{
.handle = fd,
.io_mode = .blocking,
.async_block_allowed = File.async_block_allowed_no,
};
}
/// Same as `createFile` but the path parameter is null-terminated.
pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
if (builtin.os.tag == .windows) {