| author | |
| committer | |
| log | ade2d0c6a28009ac505b4863079ede3ba64fcdd1 |
| tree | 9a6a203309c5a601fe6067bf7e8e442822066a45 |
| parent | 58f961f4cb9875bbce3070969438ecf08f392c9f |
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 compiler | 2710 | 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 { |
| 735 | 735 | ||
| 736 | test "resolve" { | 736 | test "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, "."); |
| 739 | 739 | ||
| 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" { |
| 802 | 802 | ||
| 803 | test "resolvePosix" { | 803 | test "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, "."); |
| 806 | 806 | ||
| 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, "."); |
| 1220 | 1220 | ||
| 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 |
| 47 | 47 | ||
| 48 | test "accessAbsolute" { | 48 | test "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, "."); |
| 51 | 51 | ||
| 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" { |
| 66 | 66 | ||
| 67 | test "openDirAbsolute" { | 67 | test "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, "."); |
| 70 | 70 | ||
| 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 .." { |
| 103 | 103 | ||
| 104 | test "readLinkAbsolute" { | 104 | test "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, "."); |
| 107 | 107 | ||
| 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" { |
| 512 | 512 | ||
| 513 | test "renameAbsolute" { | 513 | test "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, "."); |
| 516 | 516 | ||
| 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)" { |
| 947 | 947 | ||
| 948 | test "walker" { | 948 | test "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, "."); |
| 951 | 951 | ||
| 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" { |
| 998 | 998 | ||
| 999 | test ". and .. in fs.Dir functions" { | 999 | test ". 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, "."); |
| 1002 | 1002 | ||
| 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" { |
| 1027 | 1027 | ||
| 1028 | test ". and .. in absolute functions" { | 1028 | test ". 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, "."); |
| 1031 | 1031 | ||
| 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 | } |
| 196 | 196 | ||
| 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" { |
| 224 | 235 | ||
| 225 | try preopens.populate(); | 236 | try preopens.populate(); |
| 226 | 237 | ||
| 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; |
| 1432 | 1432 | ||
| 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"); |
| 1484 | 1486 | ||
| 1485 | // If the path is absolute, we need to lookup a containing Preopen | 1487 | 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 }); |
| 1488 | 1504 | ||
| 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 root | 1524 | // 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; |
| 1511 | 1527 | ||
| 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 | } |
| 1982 | 1984 | ||
| 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 not | 5094 | 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 | } | ||
| 5107 | 5099 | ||
| 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 path | 5104 | fn 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 | } |
| 5122 | 5134 | ||
| 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" { |
| 49 | 49 | ||
| 50 | test "open smoke test" { | 50 | test "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, "."); |
| 53 | 53 | ||
| 54 | // TODO verify file attributes using `fstat` | 54 | // TODO verify file attributes using `fstat` |
| 55 | 55 | ||
| ... | @@ -104,7 +104,7 @@ test "open smoke test" { | ... | @@ -104,7 +104,7 @@ test "open smoke test" { |
| 104 | 104 | ||
| 105 | test "openat smoke test" { | 105 | test "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, "."); |
| 108 | 108 | ||
| 109 | // TODO verify file attributes using `fstatat` | 109 | // TODO verify file attributes using `fstatat` |
| 110 | 110 | ||
| ... | @@ -141,7 +141,7 @@ test "openat smoke test" { | ... | @@ -141,7 +141,7 @@ test "openat smoke test" { |
| 141 | 141 | ||
| 142 | test "symlink with relative paths" { | 142 | test "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, "."); |
| 145 | 145 | ||
| 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" { |
| 237 | 237 | ||
| 238 | test "linkat with different directories" { | 238 | test "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" { |
| 890 | 890 | ||
| 891 | test "rename smoke test" { | 891 | test "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, "."); |
| 894 | 894 | ||
| 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" { |
| 947 | 947 | ||
| 948 | test "access smoke test" { | 948 | test "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, "."); |
| 951 | 951 | ||
| 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() catch | 328 | 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" }) orelse | 330 | 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"); |
| 332 | 332 | ||
| 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. |