From 05fb3e79fecc689def1a4186da8783546e17f1ae Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 1 May 2020 22:27:11 +0200 Subject: [PATCH] Make std.fs.cwd() return preopen for "." if exists This commit adds WASI specific impl of `std.fs.cwd()` in which we emulate the `cwd` behaviour by inquiring the runtime for a "." preopen if available. This is OK for simple relative ops, but will not work for any ops which require absolute paths. --- lib/std/fs.zig | 23 ++++++++++++++++++----- lib/std/os.zig | 6 +++--- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/std/fs.zig b/lib/std/fs.zig index a175ce493..be729eb29 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -591,7 +591,7 @@ pub const Dir = struct { return self.openFileZ(&path_c, flags); } - pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { + 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) { @@ -703,11 +703,12 @@ pub const Dir = struct { 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; + 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) { - rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET; + rights |= wasi.RIGHT_FD_READ | wasi.RIGHT_FD_TELL | wasi.RIGHT_FD_FILESTAT_GET; } if (flags.truncate) { oflags |= wasi.O_TRUNC; @@ -1438,6 +1439,18 @@ pub const Dir = struct { pub fn cwd() Dir { if (builtin.os.tag == .windows) { return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle }; + } else if (builtin.os.tag == .wasi) { + const wasi = os.wasi; + // On WASI we indeed don't have a concept of cwd; however, we can approximate it with + // trying to obtain a preopen for ".". + // TODO `cwd()` should be a fallible operation if we're going to support WASI this way. + var fd: wasi.fd_t = undefined; + var prefix: usize = undefined; + switch (wasi.resolve_preopen(".", &fd, &prefix)) { + 0 => {}, + else => {}, + } + return Dir{ .fd = fd }; } else { return Dir{ .fd = os.AT_FDCWD }; } diff --git a/lib/std/os.zig b/lib/std/os.zig index eab623d93..c3f5bc55e 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -943,13 +943,13 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) Ope return openatZ(dir_fd, &file_path_c, flags, mode); } -pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, oflags: wasi.oflag_t, fdflags: wasi.fdflag_t, rights: wasi.rights_t) OpenError!fd_t { - switch (wasi.path_open(dirfd, 0x0, &file_path, file_path.len, oflags, rights, 0x0, fdflags, &fd)) { +pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, oflags: wasi.oflags_t, fdflags: wasi.fdflags_t, rights: wasi.rights_t) OpenError!fd_t { + var fd: fd_t = undefined; + switch (wasi.path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) { 0 => {}, // TODO map errors else => |err| return unexpectedErrno(err), } - return fd; }