aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-11-23 14:51:22 -0500
committerGitHub <noreply@github.com>2022-11-23 14:51:22 -0500
commit81d2135ca6ebd71b8c121a19957c8fbf7f87125b (patch)
treee6ed1b33a6a02479e661b11103c5f7b8342d2345 /lib/std
parent32ce2f91a92c23d46c6836a6dd68ae0f08bb04c5 (diff)
parent984acae12d0dd4e24577c485b90b313c5c2d2089 (diff)
downloadzig-81d2135ca6ebd71b8c121a19957c8fbf7f87125b.tar.gz
zig-81d2135ca6ebd71b8c121a19957c8fbf7f87125b.zip
Merge pull request #13596 from ziglang/cache-path-prefixes
Cache: introduce prefixes to manifests
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/fs/path.zig390
-rw-r--r--lib/std/fs/test.zig4
-rw-r--r--lib/std/fs/wasi.zig5
3 files changed, 183 insertions, 216 deletions
diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig
index 0d102493cf..feacf38daf 100644
--- a/lib/std/fs/path.zig
+++ b/lib/std/fs/path.zig
@@ -467,55 +467,49 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) ![]u8 {
/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
/// Note: all usage of this function should be audited due to the existence of symlinks.
/// Without performing actual syscalls, resolving `..` could be incorrect.
+/// This API may break in the future: https://github.com/ziglang/zig/issues/13613
pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 {
- if (paths.len == 0) {
- assert(native_os == .windows); // resolveWindows called on non windows can't use getCwd
- return process.getCwdAlloc(allocator);
- }
+ assert(paths.len > 0);
// determine which disk designator we will result with, if any
var result_drive_buf = "_:".*;
- var result_disk_designator: []const u8 = "";
- var have_drive_kind = WindowsPath.Kind.None;
+ var disk_designator: []const u8 = "";
+ var drive_kind = WindowsPath.Kind.None;
var have_abs_path = false;
var first_index: usize = 0;
- var max_size: usize = 0;
for (paths) |p, i| {
const parsed = windowsParsePath(p);
if (parsed.is_abs) {
have_abs_path = true;
first_index = i;
- max_size = result_disk_designator.len;
}
switch (parsed.kind) {
- WindowsPath.Kind.Drive => {
+ .Drive => {
result_drive_buf[0] = ascii.toUpper(parsed.disk_designator[0]);
- result_disk_designator = result_drive_buf[0..];
- have_drive_kind = WindowsPath.Kind.Drive;
+ disk_designator = result_drive_buf[0..];
+ drive_kind = WindowsPath.Kind.Drive;
},
- WindowsPath.Kind.NetworkShare => {
- result_disk_designator = parsed.disk_designator;
- have_drive_kind = WindowsPath.Kind.NetworkShare;
+ .NetworkShare => {
+ disk_designator = parsed.disk_designator;
+ drive_kind = WindowsPath.Kind.NetworkShare;
},
- WindowsPath.Kind.None => {},
+ .None => {},
}
- max_size += p.len + 1;
}
// if we will result with a disk designator, loop again to determine
// which is the last time the disk designator is absolutely specified, if any
// and count up the max bytes for paths related to this disk designator
- if (have_drive_kind != WindowsPath.Kind.None) {
+ if (drive_kind != WindowsPath.Kind.None) {
have_abs_path = false;
first_index = 0;
- max_size = result_disk_designator.len;
var correct_disk_designator = false;
for (paths) |p, i| {
const parsed = windowsParsePath(p);
if (parsed.kind != WindowsPath.Kind.None) {
- if (parsed.kind == have_drive_kind) {
- correct_disk_designator = compareDiskDesignators(have_drive_kind, result_disk_designator, parsed.disk_designator);
+ if (parsed.kind == drive_kind) {
+ correct_disk_designator = compareDiskDesignators(drive_kind, disk_designator, parsed.disk_designator);
} else {
continue;
}
@@ -525,92 +519,51 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 {
}
if (parsed.is_abs) {
first_index = i;
- max_size = result_disk_designator.len;
have_abs_path = true;
}
- max_size += p.len + 1;
}
}
- // Allocate result and fill in the disk designator, calling getCwd if we have to.
- var result: []u8 = undefined;
- var result_index: usize = 0;
-
- if (have_abs_path) {
- switch (have_drive_kind) {
- WindowsPath.Kind.Drive => {
- result = try allocator.alloc(u8, max_size);
+ // Allocate result and fill in the disk designator.
+ var result = std.ArrayList(u8).init(allocator);
+ defer result.deinit();
- mem.copy(u8, result, result_disk_designator);
- result_index += result_disk_designator.len;
+ const disk_designator_len: usize = l: {
+ if (!have_abs_path) break :l 0;
+ switch (drive_kind) {
+ .Drive => {
+ try result.appendSlice(disk_designator);
+ break :l disk_designator.len;
},
- WindowsPath.Kind.NetworkShare => {
- result = try allocator.alloc(u8, max_size);
+ .NetworkShare => {
var it = mem.tokenize(u8, paths[first_index], "/\\");
const server_name = it.next().?;
const other_name = it.next().?;
- result[result_index] = '\\';
- result_index += 1;
- result[result_index] = '\\';
- result_index += 1;
- mem.copy(u8, result[result_index..], server_name);
- result_index += server_name.len;
- result[result_index] = '\\';
- result_index += 1;
- mem.copy(u8, result[result_index..], other_name);
- result_index += other_name.len;
-
- result_disk_designator = result[0..result_index];
+ try result.ensureUnusedCapacity(2 + 1 + server_name.len + other_name.len);
+ result.appendSliceAssumeCapacity("\\\\");
+ result.appendSliceAssumeCapacity(server_name);
+ result.appendAssumeCapacity('\\');
+ result.appendSliceAssumeCapacity(other_name);
+
+ break :l result.items.len;
},
- WindowsPath.Kind.None => {
- assert(native_os == .windows); // resolveWindows called on non windows can't use getCwd
- const cwd = try process.getCwdAlloc(allocator);
- defer allocator.free(cwd);
- const parsed_cwd = windowsParsePath(cwd);
- result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);
- mem.copy(u8, result, parsed_cwd.disk_designator);
- result_index += parsed_cwd.disk_designator.len;
- result_disk_designator = result[0..parsed_cwd.disk_designator.len];
- if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
- result[0] = ascii.toUpper(result[0]);
- }
- have_drive_kind = parsed_cwd.kind;
+ .None => {
+ break :l 1;
},
}
- } else {
- assert(native_os == .windows); // resolveWindows called on non windows can't use getCwd
- // TODO call get cwd for the result_disk_designator instead of the global one
- const cwd = try process.getCwdAlloc(allocator);
- defer allocator.free(cwd);
-
- result = try allocator.alloc(u8, max_size + cwd.len + 1);
-
- mem.copy(u8, result, cwd);
- result_index += cwd.len;
- const parsed_cwd = windowsParsePath(result[0..result_index]);
- result_disk_designator = parsed_cwd.disk_designator;
- if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
- result[0] = ascii.toUpper(result[0]);
- // Remove the trailing slash if present, eg. if the cwd is a root
- // directory.
- if (cwd.len > 0 and cwd[cwd.len - 1] == sep_windows) {
- result_index -= 1;
- }
- }
- have_drive_kind = parsed_cwd.kind;
- }
- errdefer allocator.free(result);
+ };
- // Now we know the disk designator to use, if any, and what kind it is. And our result
- // is big enough to append all the paths to.
var correct_disk_designator = true;
+ var negative_count: usize = 0;
+
for (paths[first_index..]) |p| {
const parsed = windowsParsePath(p);
- if (parsed.kind != WindowsPath.Kind.None) {
- if (parsed.kind == have_drive_kind) {
- correct_disk_designator = compareDiskDesignators(have_drive_kind, result_disk_designator, parsed.disk_designator);
+ if (parsed.kind != .None) {
+ if (parsed.kind == drive_kind) {
+ const dd = result.items[0..disk_designator_len];
+ correct_disk_designator = compareDiskDesignators(drive_kind, dd, parsed.disk_designator);
} else {
continue;
}
@@ -619,154 +572,167 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 {
continue;
}
var it = mem.tokenize(u8, p[parsed.disk_designator.len..], "/\\");
- while (it.next()) |component| {
+ component: while (it.next()) |component| {
if (mem.eql(u8, component, ".")) {
continue;
} else if (mem.eql(u8, component, "..")) {
while (true) {
- if (result_index == 0 or result_index == result_disk_designator.len)
- break;
- result_index -= 1;
- if (result[result_index] == '\\' or result[result_index] == '/')
+ if (result.items.len == 0) {
+ negative_count += 1;
+ continue :component;
+ }
+ if (result.items.len == disk_designator_len) {
break;
+ }
+ const end_with_sep = switch (result.items[result.items.len - 1]) {
+ '\\', '/' => true,
+ else => false,
+ };
+ result.items.len -= 1;
+ if (end_with_sep) break;
}
+ } else if (!have_abs_path and result.items.len == 0) {
+ try result.appendSlice(component);
} else {
- result[result_index] = sep_windows;
- result_index += 1;
- mem.copy(u8, result[result_index..], component);
- result_index += component.len;
+ try result.ensureUnusedCapacity(1 + component.len);
+ result.appendAssumeCapacity('\\');
+ result.appendSliceAssumeCapacity(component);
}
}
}
- if (result_index == result_disk_designator.len) {
- result[result_index] = '\\';
- result_index += 1;
+ if (disk_designator_len != 0 and result.items.len == disk_designator_len) {
+ try result.append('\\');
+ return result.toOwnedSlice();
+ }
+
+ if (result.items.len == 0) {
+ if (negative_count == 0) {
+ return allocator.dupe(u8, ".");
+ } else {
+ const real_result = try allocator.alloc(u8, 3 * negative_count - 1);
+ var count = negative_count - 1;
+ var i: usize = 0;
+ while (count > 0) : (count -= 1) {
+ real_result[i..][0..3].* = "..\\".*;
+ i += 3;
+ }
+ real_result[i..][0..2].* = "..".*;
+ return real_result;
+ }
}
- return allocator.shrink(result, result_index);
+ if (negative_count == 0) {
+ return result.toOwnedSlice();
+ } else {
+ const real_result = try allocator.alloc(u8, 3 * negative_count + result.items.len);
+ var count = negative_count;
+ var i: usize = 0;
+ while (count > 0) : (count -= 1) {
+ real_result[i..][0..3].* = "..\\".*;
+ i += 3;
+ }
+ mem.copy(u8, real_result[i..], result.items);
+ return real_result;
+ }
}
/// This function is like a series of `cd` statements executed one after another.
/// It resolves "." and "..".
/// The result does not have a trailing path separator.
-/// If all paths are relative it uses the current working directory as a starting point.
-/// Note: all usage of this function should be audited due to the existence of symlinks.
-/// Without performing actual syscalls, resolving `..` could be incorrect.
-pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) ![]u8 {
- if (paths.len == 0) {
- assert(native_os != .windows); // resolvePosix called on windows can't use getCwd
- return process.getCwdAlloc(allocator);
- }
+/// This function does not perform any syscalls. Executing this series of path
+/// lookups on the actual filesystem may produce different results due to
+/// symlinks.
+pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
+ assert(paths.len > 0);
- var first_index: usize = 0;
- var have_abs = false;
- var max_size: usize = 0;
- for (paths) |p, i| {
- if (isAbsolutePosix(p)) {
- first_index = i;
- have_abs = true;
- max_size = 0;
- }
- max_size += p.len + 1;
- }
-
- var result: []u8 = undefined;
- var result_index: usize = 0;
+ var result = std.ArrayList(u8).init(allocator);
+ defer result.deinit();
- if (have_abs) {
- result = try allocator.alloc(u8, max_size);
- } else {
- assert(native_os != .windows); // resolvePosix called on windows can't use getCwd
- const cwd = try process.getCwdAlloc(allocator);
- defer allocator.free(cwd);
- result = try allocator.alloc(u8, max_size + cwd.len + 1);
- mem.copy(u8, result, cwd);
- result_index += cwd.len;
- }
- errdefer allocator.free(result);
+ var negative_count: usize = 0;
+ var is_abs = false;
- for (paths[first_index..]) |p| {
+ for (paths) |p| {
+ if (isAbsolutePosix(p)) {
+ is_abs = true;
+ negative_count = 0;
+ result.clearRetainingCapacity();
+ }
var it = mem.tokenize(u8, p, "/");
- while (it.next()) |component| {
+ component: while (it.next()) |component| {
if (mem.eql(u8, component, ".")) {
continue;
} else if (mem.eql(u8, component, "..")) {
while (true) {
- if (result_index == 0)
- break;
- result_index -= 1;
- if (result[result_index] == '/')
- break;
+ if (result.items.len == 0) {
+ negative_count += @boolToInt(!is_abs);
+ continue :component;
+ }
+ const ends_with_slash = result.items[result.items.len - 1] == '/';
+ result.items.len -= 1;
+ if (ends_with_slash) break;
}
+ } else if (result.items.len > 0 or is_abs) {
+ try result.ensureUnusedCapacity(1 + component.len);
+ result.appendAssumeCapacity('/');
+ result.appendSliceAssumeCapacity(component);
} else {
- result[result_index] = '/';
- result_index += 1;
- mem.copy(u8, result[result_index..], component);
- result_index += component.len;
+ try result.appendSlice(component);
}
}
}
- if (result_index == 0) {
- result[0] = '/';
- result_index += 1;
+ if (result.items.len == 0) {
+ if (is_abs) {
+ return allocator.dupe(u8, "/");
+ }
+ if (negative_count == 0) {
+ return allocator.dupe(u8, ".");
+ } else {
+ const real_result = try allocator.alloc(u8, 3 * negative_count - 1);
+ var count = negative_count - 1;
+ var i: usize = 0;
+ while (count > 0) : (count -= 1) {
+ real_result[i..][0..3].* = "../".*;
+ i += 3;
+ }
+ real_result[i..][0..2].* = "..".*;
+ return real_result;
+ }
}
- return allocator.shrink(result, result_index);
+ if (negative_count == 0) {
+ return result.toOwnedSlice();
+ } else {
+ const real_result = try allocator.alloc(u8, 3 * negative_count + result.items.len);
+ var count = negative_count;
+ var i: usize = 0;
+ while (count > 0) : (count -= 1) {
+ real_result[i..][0..3].* = "../".*;
+ i += 3;
+ }
+ mem.copy(u8, real_result[i..], result.items);
+ return real_result;
+ }
}
test "resolve" {
- if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ try testResolveWindows(&[_][]const u8{ "a\\b\\c\\", "..\\..\\.." }, "..");
+ try testResolveWindows(&[_][]const u8{"."}, ".");
- const cwd = try process.getCwdAlloc(testing.allocator);
- defer testing.allocator.free(cwd);
- if (native_os == .windows) {
- if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
- cwd[0] = ascii.toUpper(cwd[0]);
- }
- try testResolveWindows(&[_][]const u8{"."}, cwd);
- } else {
- try testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }, cwd);
- try testResolvePosix(&[_][]const u8{"."}, cwd);
- }
+ try testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }, "..");
+ try testResolvePosix(&[_][]const u8{"."}, ".");
}
test "resolveWindows" {
- if (builtin.target.cpu.arch == .aarch64) {
- // TODO https://github.com/ziglang/zig/issues/3288
- return error.SkipZigTest;
- }
- if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
- if (native_os == .windows) {
- const cwd = try process.getCwdAlloc(testing.allocator);
- defer testing.allocator.free(cwd);
- const parsed_cwd = windowsParsePath(cwd);
- {
- const expected = try join(testing.allocator, &[_][]const u8{
- parsed_cwd.disk_designator,
- "usr\\local\\lib\\zig\\std\\array_list.zig",
- });
- defer testing.allocator.free(expected);
- if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
- expected[0] = ascii.toUpper(parsed_cwd.disk_designator[0]);
- }
- try testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" }, expected);
- }
- {
- const expected = try join(testing.allocator, &[_][]const u8{
- cwd,
- "usr\\local\\lib\\zig",
- });
- defer testing.allocator.free(expected);
- if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
- expected[0] = ascii.toUpper(parsed_cwd.disk_designator[0]);
- }
- try testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" }, expected);
- }
- }
+ try testResolveWindows(
+ &[_][]const u8{ "Z:\\", "/usr/local", "lib\\zig\\std\\array_list.zig" },
+ "Z:\\usr\\local\\lib\\zig\\std\\array_list.zig",
+ );
+ try testResolveWindows(
+ &[_][]const u8{ "z:\\", "usr/local", "lib\\zig" },
+ "Z:\\usr\\local\\lib\\zig",
+ );
try testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }, "C:\\hi\\ok");
try testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }, "C:\\blah\\a");
@@ -781,12 +747,12 @@ test "resolveWindows" {
try testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }, "\\\\server\\share\\");
try testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }, "C:\\some\\dir");
try testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }, "C:\\foo\\tmp.3\\cycles\\root.js");
+
+ // Keep relative paths relative.
+ try testResolveWindows(&[_][]const u8{"a/b"}, "a\\b");
}
test "resolvePosix" {
- if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
-
try testResolvePosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");
try testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }, "/d/e");
try testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }, "/a");
@@ -797,18 +763,21 @@ test "resolvePosix" {
try testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }, "/file");
try testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }, "/absolute");
try testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }, "/foo/tmp.3/cycles/root.js");
+
+ // Keep relative paths relative.
+ try testResolvePosix(&[_][]const u8{"a/b"}, "a/b");
}
fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {
const actual = try resolveWindows(testing.allocator, paths);
defer testing.allocator.free(actual);
- try testing.expect(mem.eql(u8, actual, expected));
+ try testing.expectEqualStrings(expected, actual);
}
fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {
const actual = try resolvePosix(testing.allocator, paths);
defer testing.allocator.free(actual);
- try testing.expect(mem.eql(u8, actual, expected));
+ try testing.expectEqualStrings(expected, actual);
}
/// Strip the last component from a file path.
@@ -1089,13 +1058,15 @@ pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) !
if (parsed_from.kind != parsed_to.kind) {
break :x true;
} else switch (parsed_from.kind) {
- WindowsPath.Kind.NetworkShare => {
+ .NetworkShare => {
break :x !networkShareServersEql(parsed_to.disk_designator, parsed_from.disk_designator);
},
- WindowsPath.Kind.Drive => {
+ .Drive => {
break :x ascii.toUpper(parsed_from.disk_designator[0]) != ascii.toUpper(parsed_to.disk_designator[0]);
},
- else => unreachable,
+ .None => {
+ break :x false;
+ },
}
};
@@ -1194,13 +1165,6 @@ pub fn relativePosix(allocator: Allocator, from: []const u8, to: []const u8) ![]
}
test "relative" {
- if (builtin.target.cpu.arch == .aarch64) {
- // TODO https://github.com/ziglang/zig/issues/3288
- return error.SkipZigTest;
- }
- if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (native_os == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
-
try testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
try testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");
@@ -1226,6 +1190,10 @@ test "relative" {
try testRelativeWindows("C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz");
try testRelativeWindows("\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz");
+ try testRelativeWindows("a/b/c", "a\\b", "..");
+ try testRelativeWindows("a/b/c", "a", "..\\..");
+ try testRelativeWindows("a/b/c", "a\\b\\c\\d", "d");
+
try testRelativePosix("/var/lib", "/var", "..");
try testRelativePosix("/var/lib", "/bin", "../../bin");
try testRelativePosix("/var/lib", "/var/lib", "");
@@ -1243,13 +1211,13 @@ test "relative" {
fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) !void {
const result = try relativePosix(testing.allocator, from, to);
defer testing.allocator.free(result);
- try testing.expectEqualSlices(u8, expected_output, result);
+ try testing.expectEqualStrings(expected_output, result);
}
fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) !void {
const result = try relativeWindows(testing.allocator, from, to);
defer testing.allocator.free(result);
- try testing.expectEqualSlices(u8, expected_output, result);
+ try testing.expectEqualStrings(expected_output, result);
}
/// Returns the extension of the file name (if any).
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
index f6168054b6..00e42b6417 100644
--- a/lib/std/fs/test.zig
+++ b/lib/std/fs/test.zig
@@ -1095,7 +1095,9 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
const allocator = testing.allocator;
- const file_paths: [1][]const u8 = .{"zig-test-absolute-paths.txt"};
+ const cwd = try std.process.getCwdAlloc(allocator);
+ defer allocator.free(cwd);
+ const file_paths: [2][]const u8 = .{ cwd, "zig-test-absolute-paths.txt" };
const filename = try fs.path.resolve(allocator, &file_paths);
defer allocator.free(filename);
diff --git a/lib/std/fs/wasi.zig b/lib/std/fs/wasi.zig
index 2051215dfe..6358873ede 100644
--- a/lib/std/fs/wasi.zig
+++ b/lib/std/fs/wasi.zig
@@ -202,10 +202,7 @@ pub const PreopenList = struct {
// POSIX paths, relative to "/" or `cwd_root` depending on whether they start with "."
const path = if (cwd_root) |cwd| blk: {
const resolve_paths: []const []const u8 = if (raw_path[0] == '.') &.{ cwd, raw_path } else &.{ "/", raw_path };
- break :blk fs.path.resolve(self.buffer.allocator, resolve_paths) catch |err| switch (err) {
- error.CurrentWorkingDirectoryUnlinked => unreachable, // root is absolute, so CWD not queried
- else => |e| return e,
- };
+ break :blk try fs.path.resolve(self.buffer.allocator, resolve_paths);
} else blk: {
// If we were provided no CWD root, we preserve the preopen dir without resolving
break :blk try self.buffer.allocator.dupe(u8, raw_path);