authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-01 22:27:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-05 15:08:52+02:00
log05fb3e79fecc689def1a4186da8783546e17f1ae
treea39fedbf8e6914fb8a9679324cb2eea02b9c40c2
parent8e1cd69717e8d87f53e930bd87edb7ca701b3f0c

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.

2 files changed, 21 insertions(+), 8 deletions(-)

lib/std/fs.zig+18-5
......@@ -591,7 +591,7 @@ pub const Dir = struct {
591591 return self.openFileZ(&path_c, flags);
592592 }
593593
594 pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
594 fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
595595 var fdflags: wasi.fdflag_t = 0x0;
596596 var rights: wasi.rights_t = 0x0;
597597 if (flags.read) {
......@@ -703,11 +703,12 @@ pub const Dir = struct {
703703
704704 pub const createFileC = @compileError("deprecated: renamed to createFileZ");
705705
706 pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
707 var oflags: wasi.oflags_t = 0x0;
708 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;
706 fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
707 const wasi = os.wasi;
708 var oflags: wasi.oflags_t = wasi.O_CREAT;
709 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;
709710 if (flags.read) {
710 rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET;
711 rights |= wasi.RIGHT_FD_READ | wasi.RIGHT_FD_TELL | wasi.RIGHT_FD_FILESTAT_GET;
711712 }
712713 if (flags.truncate) {
713714 oflags |= wasi.O_TRUNC;
......@@ -1438,6 +1439,18 @@ pub const Dir = struct {
14381439pub fn cwd() Dir {
14391440 if (builtin.os.tag == .windows) {
14401441 return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };
1442 } else if (builtin.os.tag == .wasi) {
1443 const wasi = os.wasi;
1444 // On WASI we indeed don't have a concept of cwd; however, we can approximate it with
1445 // trying to obtain a preopen for ".".
1446 // TODO `cwd()` should be a fallible operation if we're going to support WASI this way.
1447 var fd: wasi.fd_t = undefined;
1448 var prefix: usize = undefined;
1449 switch (wasi.resolve_preopen(".", &fd, &prefix)) {
1450 0 => {},
1451 else => {},
1452 }
1453 return Dir{ .fd = fd };
14411454 } else {
14421455 return Dir{ .fd = os.AT_FDCWD };
14431456 }
lib/std/os.zig+3-3
......@@ -943,13 +943,13 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) Ope
943943 return openatZ(dir_fd, &file_path_c, flags, mode);
944944}
945945
946pub 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 {
947 switch (wasi.path_open(dirfd, 0x0, &file_path, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
946pub 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 {
947 var fd: fd_t = undefined;
948 switch (wasi.path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, rights, 0x0, fdflags, &fd)) {
948949 0 => {},
949950 // TODO map errors
950951 else => |err| return unexpectedErrno(err),
951952 }
952
953953 return fd;
954954}
955955