authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-02 23:21:55-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-03 14:31:49-07:00
logade2d0c6a28009ac505b4863079ede3ba64fcdd1
tree9a6a203309c5a601fe6067bf7e8e442822066a45
parent58f961f4cb9875bbce3070969438ecf08f392c9f

stdlib WASI: Add realpath() support for non-absolute Preopens


8 files changed, 95 insertions(+), 75 deletions(-)

lib/std/build.zig-2
...@@ -2707,8 +2707,6 @@ pub const LibExeObjStep = struct {...@@ -2707,8 +2707,6 @@ pub const LibExeObjStep = struct {
2707 try zig_args.append("--test-cmd");2707 try zig_args.append("--test-cmd");
2708 try zig_args.append("--dir=.");2708 try zig_args.append("--dir=.");
2709 try zig_args.append("--test-cmd");2709 try zig_args.append("--test-cmd");
2710 try zig_args.append("--mapdir=/cwd::.");
2711 try zig_args.append("--test-cmd");
2712 try zig_args.append("--allow-unknown-exports"); // TODO: Remove when stage2 is default compiler2710 try zig_args.append("--allow-unknown-exports"); // TODO: Remove when stage2 is default compiler
2713 try zig_args.append("--test-cmd-bin");2711 try zig_args.append("--test-cmd-bin");
2714 } else {2712 } else {
lib/std/fs/path.zig+4-4
...@@ -735,7 +735,7 @@ pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) ![]u8 {...@@ -735,7 +735,7 @@ pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) ![]u8 {
735735
736test "resolve" {736test "resolve" {
737 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;737 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
738 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");738 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
739739
740 const cwd = try process.getCwdAlloc(testing.allocator);740 const cwd = try process.getCwdAlloc(testing.allocator);
741 defer testing.allocator.free(cwd);741 defer testing.allocator.free(cwd);
...@@ -756,7 +756,7 @@ test "resolveWindows" {...@@ -756,7 +756,7 @@ test "resolveWindows" {
756 return error.SkipZigTest;756 return error.SkipZigTest;
757 }757 }
758 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;758 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
759 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");759 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
760 if (native_os == .windows) {760 if (native_os == .windows) {
761 const cwd = try process.getCwdAlloc(testing.allocator);761 const cwd = try process.getCwdAlloc(testing.allocator);
762 defer testing.allocator.free(cwd);762 defer testing.allocator.free(cwd);
...@@ -802,7 +802,7 @@ test "resolveWindows" {...@@ -802,7 +802,7 @@ test "resolveWindows" {
802802
803test "resolvePosix" {803test "resolvePosix" {
804 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;804 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
805 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");805 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
806806
807 try testResolvePosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");807 try testResolvePosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");
808 try testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }, "/d/e");808 try testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }, "/d/e");
...@@ -1216,7 +1216,7 @@ test "relative" {...@@ -1216,7 +1216,7 @@ test "relative" {
1216 return error.SkipZigTest;1216 return error.SkipZigTest;
1217 }1217 }
1218 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;1218 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
1219 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");1219 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
12201220
1221 try testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");1221 try testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
1222 try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");1222 try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
lib/std/fs/test.zig+7-7
...@@ -47,7 +47,7 @@ fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !vo...@@ -47,7 +47,7 @@ fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !vo
4747
48test "accessAbsolute" {48test "accessAbsolute" {
49 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;49 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
50 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");50 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
5151
52 var tmp = tmpDir(.{});52 var tmp = tmpDir(.{});
53 defer tmp.cleanup();53 defer tmp.cleanup();
...@@ -66,7 +66,7 @@ test "accessAbsolute" {...@@ -66,7 +66,7 @@ test "accessAbsolute" {
6666
67test "openDirAbsolute" {67test "openDirAbsolute" {
68 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;68 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
69 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");69 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
7070
71 var tmp = tmpDir(.{});71 var tmp = tmpDir(.{});
72 defer tmp.cleanup();72 defer tmp.cleanup();
...@@ -103,7 +103,7 @@ test "openDir cwd parent .." {...@@ -103,7 +103,7 @@ test "openDir cwd parent .." {
103103
104test "readLinkAbsolute" {104test "readLinkAbsolute" {
105 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;105 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
106 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");106 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
107107
108 var tmp = tmpDir(.{});108 var tmp = tmpDir(.{});
109 defer tmp.cleanup();109 defer tmp.cleanup();
...@@ -512,7 +512,7 @@ test "rename" {...@@ -512,7 +512,7 @@ test "rename" {
512512
513test "renameAbsolute" {513test "renameAbsolute" {
514 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;514 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
515 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");515 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
516516
517 var tmp_dir = tmpDir(.{});517 var tmp_dir = tmpDir(.{});
518 defer tmp_dir.cleanup();518 defer tmp_dir.cleanup();
...@@ -947,7 +947,7 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {...@@ -947,7 +947,7 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
947947
948test "walker" {948test "walker" {
949 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;949 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
950 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");950 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
951951
952 var tmp = tmpDir(.{ .iterate = true });952 var tmp = tmpDir(.{ .iterate = true });
953 defer tmp.cleanup();953 defer tmp.cleanup();
...@@ -998,7 +998,7 @@ test "walker" {...@@ -998,7 +998,7 @@ test "walker" {
998998
999test ". and .. in fs.Dir functions" {999test ". and .. in fs.Dir functions" {
1000 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;1000 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
1001 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");1001 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
10021002
1003 var tmp = tmpDir(.{});1003 var tmp = tmpDir(.{});
1004 defer tmp.cleanup();1004 defer tmp.cleanup();
...@@ -1027,7 +1027,7 @@ test ". and .. in fs.Dir functions" {...@@ -1027,7 +1027,7 @@ test ". and .. in fs.Dir functions" {
10271027
1028test ". and .. in absolute functions" {1028test ". and .. in absolute functions" {
1029 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;1029 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
1030 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");1030 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
10311031
1032 var tmp = tmpDir(.{});1032 var tmp = tmpDir(.{});
1033 defer tmp.cleanup();1033 defer tmp.cleanup();
lib/std/fs/wasi.zig+13-2
...@@ -194,6 +194,17 @@ pub const PreopenList = struct {...@@ -194,6 +194,17 @@ pub const PreopenList = struct {
194 return null;194 return null;
195 }195 }
196196
197 /// Find preopen by fd. If the preopen exists, return it.
198 /// Otherwise, return `null`.
199 pub fn findByFd(self: Self, fd: fd_t) ?Preopen {
200 for (self.buffer.items) |preopen| {
201 if (preopen.fd == fd) {
202 return preopen;
203 }
204 }
205 return null;
206 }
207
197 /// Find preopen by type. If the preopen exists, return it.208 /// Find preopen by type. If the preopen exists, return it.
198 /// Otherwise, return `null`.209 /// Otherwise, return `null`.
199 pub fn find(self: Self, preopen_type: PreopenType) ?*const Preopen {210 pub fn find(self: Self, preopen_type: PreopenType) ?*const Preopen {
...@@ -224,6 +235,6 @@ test "extracting WASI preopens" {...@@ -224,6 +235,6 @@ test "extracting WASI preopens" {
224235
225 try preopens.populate();236 try preopens.populate();
226237
227 const preopen = preopens.find(PreopenType{ .Dir = "/cwd" }) orelse unreachable;238 const preopen = preopens.find(PreopenType{ .Dir = "." }) orelse unreachable;
228 try std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "/cwd" }));239 try std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "." }));
229}240}
lib/std/os.zig+62-50
...@@ -1431,6 +1431,8 @@ var wasi_cwd = if (builtin.os.tag == .wasi and !builtin.link_libc) struct {...@@ -1431,6 +1431,8 @@ var wasi_cwd = if (builtin.os.tag == .wasi and !builtin.link_libc) struct {
1431}{} else undefined;1431}{} else undefined;
14321432
1433/// Initialize the available Preopen list on WASI and set the CWD to `cwd_init`.1433/// Initialize the available Preopen list on WASI and set the CWD to `cwd_init`.
1434/// Note that `cwd_init` corresponds to a Preopen directory, not necessarily
1435/// a POSIX path. For example, "." matches a Preopen provided with `--dir=.`
1434///1436///
1435/// This must be called before using any relative or absolute paths with `std.os` 1437/// This must be called before using any relative or absolute paths with `std.os`
1436/// functions, if you are on WASI without linking libc.1438/// functions, if you are on WASI without linking libc.
...@@ -1482,8 +1484,22 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe...@@ -1482,8 +1484,22 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe
1482 if (wasi_cwd.preopens == null) @panic("On WASI, `initPreopensWasi` must be called to initialize preopens " ++1484 if (wasi_cwd.preopens == null) @panic("On WASI, `initPreopensWasi` must be called to initialize preopens " ++
1483 "before using any CWD-relative or absolute paths.\n");1485 "before using any CWD-relative or absolute paths.\n");
14841486
1485 // If the path is absolute, we need to lookup a containing Preopen1487 if (mem.startsWith(u8, path, "/preopens/fd/")) {
1486 const abs_path = std.fs.path.resolve(alloc, &.{ "/", path }) catch return error.NameTooLong;1488 // "/preopens/fd/<N>" is a special prefix, which refers to a Preopen directly by fd
1489 const fd_start = "/preopens/fd/".len;
1490 const fd_end = mem.indexOfScalarPos(u8, path, fd_start, '/') orelse path.len;
1491 const fd = std.fmt.parseUnsigned(fd_t, path[fd_start..fd_end], 10) catch unreachable;
1492 const rel_path = if (path.len > fd_end + 1) path[fd_end + 1 ..] else ".";
1493
1494 if (preopen) |p| p.* = wasi_cwd.preopens.?.findByFd(fd);
1495 return RelativePath{
1496 .dir_fd = fd,
1497 .relative_path = alloc.dupe(u8, rel_path) catch return error.NameTooLong,
1498 };
1499 }
1500
1501 // For any other absolute path, we need to lookup a containing Preopen
1502 const abs_path = fs.path.resolve(alloc, &.{ "/", path }) catch return error.NameTooLong;
1487 const preopen_uri = wasi_cwd.preopens.?.findContaining(.{ .Dir = abs_path });1503 const preopen_uri = wasi_cwd.preopens.?.findContaining(.{ .Dir = abs_path });
14881504
1489 if (preopen_uri) |po| {1505 if (preopen_uri) |po| {
...@@ -1507,7 +1523,7 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe...@@ -1507,7 +1523,7 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe
1507 // First resolve a combined path, where the "/" corresponds to `cwd.dir_fd`1523 // First resolve a combined path, where the "/" corresponds to `cwd.dir_fd`
1508 // not the true filesystem root1524 // not the true filesystem root
1509 const paths = &.{ "/", cwd.relative_path, path };1525 const paths = &.{ "/", cwd.relative_path, path };
1510 const resolved_path = std.fs.path.resolve(alloc, paths) catch return error.NameTooLong;1526 const resolved_path = fs.path.resolve(alloc, paths) catch return error.NameTooLong;
15111527
1512 // Strip off the fake root to get the relative path w.r.t. `cwd.dir_fd`1528 // Strip off the fake root to get the relative path w.r.t. `cwd.dir_fd`
1513 const resolved_relative_path = resolved_path[1..];1529 const resolved_relative_path = resolved_path[1..];
...@@ -1956,28 +1972,14 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {...@@ -1956,28 +1972,14 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
1956 if (builtin.os.tag == .windows) {1972 if (builtin.os.tag == .windows) {
1957 return windows.GetCurrentDirectory(out_buffer);1973 return windows.GetCurrentDirectory(out_buffer);
1958 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {1974 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
1959 var allocator = std.heap.FixedBufferAllocator.init(out_buffer);1975 var buf: [MAX_PATH_BYTES]u8 = undefined;
1960 var alloc = allocator.allocator();1976 const path = realpathWasi(".", &buf) catch |err| switch (err) {
1961 if (wasi_cwd.cwd) |cwd| {1977 error.NameTooLong => return error.NameTooLong,
1962 if (wasi_cwd.cwd_preopen) |po| {1978 error.InvalidHandle => return error.CurrentWorkingDirectoryUnlinked,
1963 var base_cwd_dir = switch (po.@"type") {1979 };
1964 .Dir => |dir| dir,1980 if (out_buffer.len < path.len) return error.NameTooLong;
1965 };1981 std.mem.copy(u8, out_buffer, path);
1966 if (!fs.path.isAbsolute(base_cwd_dir)) {1982 return out_buffer[0..path.len];
1967 // This preopen is not based on an absolute path, so we have
1968 // no way to know the absolute path of the CWD
1969 return error.CurrentWorkingDirectoryUnlinked;
1970 }
1971 const paths = &.{ base_cwd_dir, cwd.relative_path };
1972 return std.fs.path.resolve(alloc, paths) catch return error.NameTooLong;
1973 } else {
1974 // The CWD is not rooted to an existing Preopen,
1975 // so we have no way to know its absolute path
1976 return error.CurrentWorkingDirectoryUnlinked;
1977 }
1978 } else {
1979 return alloc.dupe(u8, "/") catch return error.NameTooLong;
1980 }
1981 }1983 }
19821984
1983 const err = if (builtin.link_libc) blk: {1985 const err = if (builtin.link_libc) blk: {
...@@ -5089,35 +5091,45 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE...@@ -5089,35 +5091,45 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
5089 const pathname_w = try windows.sliceToPrefixedFileW(pathname);5091 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
5090 return realpathW(pathname_w.span(), out_buffer);5092 return realpathW(pathname_w.span(), out_buffer);
5091 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {5093 } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
5092 // NOTE: This emulation is incomplete. Symbolic links are not5094 return realpathWasi(pathname, out_buffer);
5093 // currently expanded during path canonicalization.5095 }
5094 var alloc = std.heap.FixedBufferAllocator.init(out_buffer);5096 const pathname_c = try toPosixPath(pathname);
5095 if (fs.path.isAbsolute(pathname))5097 return realpathZ(&pathname_c, out_buffer);
5096 return try fs.path.resolve(alloc.allocator(), &.{pathname}) catch error.NameTooLong;5098}
5097 if (wasi_cwd.cwd) |cwd| {
5098 if (wasi_cwd.cwd_preopen) |po| {
5099 var base_cwd_dir = switch (po.@"type") {
5100 .Dir => |dir| dir,
5101 };
5102 if (!fs.path.isAbsolute(base_cwd_dir)) {
5103 // This preopen is not based on an absolute path, so we have
5104 // no way to know the absolute path of the CWD
5105 return error.InvalidHandle;
5106 }
51075099
5108 const paths = &.{ base_cwd_dir, cwd.relative_path, pathname };5100/// Return an emulated canonicalized absolute pathname on WASI.
5109 return fs.path.resolve(alloc.allocator(), paths) catch error.NameTooLong;5101///
5110 } else {5102/// NOTE: This emulation is incomplete. Symbolic links are not
5111 // The CWD is not rooted to an existing Preopen,5103/// currently expanded during path canonicalization.
5112 // so we have no way to know its absolute path5104fn realpathWasi(pathname: []const u8, out_buffer: []u8) ![]u8 {
5113 return error.InvalidHandle;5105 var alloc = std.heap.FixedBufferAllocator.init(out_buffer);
5114 }5106 if (fs.path.isAbsolute(pathname))
5107 return try fs.path.resolve(alloc.allocator(), &.{pathname}) catch error.NameTooLong;
5108 if (wasi_cwd.cwd) |cwd| {
5109 if (wasi_cwd.cwd_preopen) |po| {
5110 var base_cwd_dir = switch (po.@"type") {
5111 .Dir => |dir| dir,
5112 };
5113 const paths: [][]const u8 = if (fs.path.isAbsolute(base_cwd_dir)) blk: {
5114 break :blk &.{ base_cwd_dir, cwd.relative_path, pathname };
5115 } else blk: {
5116 // No absolute path is associated with this preopen, so
5117 // instead we use a special "/preopens/fd/<N>/" prefix
5118 var buf: [16]u8 = undefined;
5119 var fbs = std.io.fixedBufferStream(&buf);
5120 std.fmt.formatInt(po.fd, 10, .lower, .{}, fbs.writer()) catch return error.NameTooLong;
5121 break :blk &.{ "/preopens/fd/", fbs.getWritten(), cwd.relative_path, pathname };
5122 };
5123
5124 return fs.path.resolve(alloc.allocator(), paths) catch error.NameTooLong;
5115 } else {5125 } else {
5116 return try fs.path.resolve(alloc.allocator(), &.{ "/", pathname }) catch error.NameTooLong;5126 // The CWD is not rooted to an existing Preopen,
5127 // so we have no way to know its absolute path
5128 return error.InvalidHandle;
5117 }5129 }
5130 } else {
5131 return try fs.path.resolve(alloc.allocator(), &.{ "/", pathname }) catch error.NameTooLong;
5118 }5132 }
5119 const pathname_c = try toPosixPath(pathname);
5120 return realpathZ(&pathname_c, out_buffer);
5121}5133}
51225134
5123/// Same as `realpath` except `pathname` is null-terminated.5135/// Same as `realpath` except `pathname` is null-terminated.
lib/std/os/test.zig+7-7
...@@ -49,7 +49,7 @@ test "chdir smoke test" {...@@ -49,7 +49,7 @@ test "chdir smoke test" {
4949
50test "open smoke test" {50test "open smoke test" {
51 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;51 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
52 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");52 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
5353
54 // TODO verify file attributes using `fstat`54 // TODO verify file attributes using `fstat`
5555
...@@ -104,7 +104,7 @@ test "open smoke test" {...@@ -104,7 +104,7 @@ test "open smoke test" {
104104
105test "openat smoke test" {105test "openat smoke test" {
106 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;106 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
107 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");107 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
108108
109 // TODO verify file attributes using `fstatat`109 // TODO verify file attributes using `fstatat`
110110
...@@ -141,7 +141,7 @@ test "openat smoke test" {...@@ -141,7 +141,7 @@ test "openat smoke test" {
141141
142test "symlink with relative paths" {142test "symlink with relative paths" {
143 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;143 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
144 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");144 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
145145
146 const cwd = fs.cwd();146 const cwd = fs.cwd();
147 cwd.deleteFile("file.txt") catch {};147 cwd.deleteFile("file.txt") catch {};
...@@ -197,7 +197,7 @@ test "link with relative paths" {...@@ -197,7 +197,7 @@ test "link with relative paths" {
197 if (builtin.link_libc) {197 if (builtin.link_libc) {
198 return error.SkipZigTest;198 return error.SkipZigTest;
199 } else {199 } else {
200 try os.initPreopensWasi(std.heap.page_allocator, "/cwd");200 try os.initPreopensWasi(std.heap.page_allocator, ".");
201 }201 }
202 },202 },
203 .linux, .solaris => {},203 .linux, .solaris => {},
...@@ -237,7 +237,7 @@ test "link with relative paths" {...@@ -237,7 +237,7 @@ test "link with relative paths" {
237237
238test "linkat with different directories" {238test "linkat with different directories" {
239 switch (native_os) {239 switch (native_os) {
240 .wasi => if (!builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd"),240 .wasi => if (!builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "."),
241 .linux, .solaris => {},241 .linux, .solaris => {},
242 else => return error.SkipZigTest,242 else => return error.SkipZigTest,
243 }243 }
...@@ -890,7 +890,7 @@ test "POSIX file locking with fcntl" {...@@ -890,7 +890,7 @@ test "POSIX file locking with fcntl" {
890890
891test "rename smoke test" {891test "rename smoke test" {
892 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;892 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
893 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");893 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
894894
895 var tmp = tmpDir(.{});895 var tmp = tmpDir(.{});
896 defer tmp.cleanup();896 defer tmp.cleanup();
...@@ -947,7 +947,7 @@ test "rename smoke test" {...@@ -947,7 +947,7 @@ test "rename smoke test" {
947947
948test "access smoke test" {948test "access smoke test" {
949 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;949 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
950 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/cwd");950 if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, ".");
951951
952 var tmp = tmpDir(.{});952 var tmp = tmpDir(.{});
953 defer tmp.cleanup();953 defer tmp.cleanup();
lib/std/testing.zig+2-2
...@@ -327,8 +327,8 @@ fn getCwdOrWasiPreopen() std.fs.Dir {...@@ -327,8 +327,8 @@ fn getCwdOrWasiPreopen() std.fs.Dir {
327 defer preopens.deinit();327 defer preopens.deinit();
328 preopens.populate() catch328 preopens.populate() catch
329 @panic("unable to make tmp dir for testing: unable to populate preopens");329 @panic("unable to make tmp dir for testing: unable to populate preopens");
330 const preopen = preopens.find(std.fs.wasi.PreopenType{ .Dir = "/cwd" }) orelse330 const preopen = preopens.find(std.fs.wasi.PreopenType{ .Dir = "." }) orelse
331 @panic("unable to make tmp dir for testing: didn't find '/cwd' in the preopens");331 @panic("unable to make tmp dir for testing: didn't find '.' in the preopens");
332332
333 return std.fs.Dir{ .fd = preopen.fd };333 return std.fs.Dir{ .fd = preopen.fd };
334 } else {334 } else {
src/test.zig-1
...@@ -1188,7 +1188,6 @@ pub const TestContext = struct {...@@ -1188,7 +1188,6 @@ pub const TestContext = struct {
1188 .wasmtime => |wasmtime_bin_name| if (enable_wasmtime) {1188 .wasmtime => |wasmtime_bin_name| if (enable_wasmtime) {
1189 try argv.append(wasmtime_bin_name);1189 try argv.append(wasmtime_bin_name);
1190 try argv.append("--dir=.");1190 try argv.append("--dir=.");
1191 try argv.append("--mapdir=/cwd::.");
1192 try argv.append(exe_path);1191 try argv.append(exe_path);
1193 } else {1192 } else {
1194 return; // wasmtime not available; pass test.1193 return; // wasmtime not available; pass test.