Commit e73170f972
lib/std/fs/test.zig
@@ -48,8 +48,7 @@ fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !vo
}
test "accessAbsolute" {
- if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
@@ -67,8 +66,7 @@ test "accessAbsolute" {
}
test "openDirAbsolute" {
- if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
@@ -104,8 +102,7 @@ test "openDir cwd parent .." {
}
test "readLinkAbsolute" {
- if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
@@ -187,8 +184,6 @@ test "Dir.Iterator" {
}
test "Dir.Iterator many entries" {
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
-
var tmp_dir = tmpIterableDir(.{});
defer tmp_dir.cleanup();
@@ -638,8 +633,7 @@ test "rename" {
}
test "renameAbsolute" {
- if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
var tmp_dir = tmpDir(.{});
defer tmp_dir.cleanup();
@@ -1149,7 +1143,6 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
test "walker" {
if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
var tmp = tmpIterableDir(.{});
defer tmp.cleanup();
@@ -1203,7 +1196,6 @@ test "walker" {
test "walker without fully iterating" {
if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
var tmp = tmpIterableDir(.{});
defer tmp.cleanup();
@@ -1227,7 +1219,6 @@ test "walker without fully iterating" {
test ". and .. in fs.Dir functions" {
if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
var tmp = tmpDir(.{});
defer tmp.cleanup();
@@ -1255,8 +1246,7 @@ test ". and .. in fs.Dir functions" {
}
test ". and .. in absolute functions" {
- if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
- if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
lib/std/os/test.zig
@@ -22,8 +22,7 @@ const Dir = std.fs.Dir;
const ArenaAllocator = std.heap.ArenaAllocator;
test "chdir smoke test" {
- 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, "/preopens/cwd");
+ if (native_os == .wasi) return error.SkipZigTest;
// Get current working directory path
var old_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
@@ -75,8 +74,7 @@ test "chdir smoke test" {
}
test "open smoke test" {
- 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 == .wasi) return error.SkipZigTest;
// TODO verify file attributes using `fstat`
@@ -131,7 +129,6 @@ test "open smoke test" {
test "openat smoke test" {
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, "/");
// TODO verify file attributes using `fstatat`
@@ -168,7 +165,6 @@ test "openat smoke test" {
test "symlink with relative paths" {
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, "/");
const cwd = fs.cwd();
cwd.deleteFile("file.txt") catch {};
@@ -219,15 +215,10 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
}
test "link with relative paths" {
+ if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
+
switch (native_os) {
- .wasi => {
- if (builtin.link_libc) {
- return error.SkipZigTest;
- } else {
- try os.initPreopensWasi(std.heap.page_allocator, "/");
- }
- },
- .linux, .solaris => {},
+ .wasi, .linux, .solaris => {},
else => return error.SkipZigTest,
}
var cwd = fs.cwd();
@@ -263,9 +254,10 @@ test "link with relative paths" {
}
test "linkat with different directories" {
+ if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
+
switch (native_os) {
- .wasi => if (!builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/"),
- .linux, .solaris => {},
+ .wasi, .linux, .solaris => {},
else => return error.SkipZigTest,
}
var cwd = fs.cwd();
@@ -950,8 +942,7 @@ test "POSIX file locking with fcntl" {
}
test "rename smoke test" {
- 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 == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
@@ -1007,8 +998,7 @@ test "rename smoke test" {
}
test "access smoke test" {
- 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 == .wasi) return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
lib/std/os/wasi.zig
@@ -1,6 +1,7 @@
// wasi_snapshot_preview1 spec available (in witx format) here:
// * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
// * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx
+const builtin = @import("builtin");
const std = @import("std");
const assert = std.debug.assert;
@@ -157,7 +158,12 @@ pub const IOV_MAX = 1024;
pub const AT = struct {
pub const REMOVEDIR: u32 = 0x4;
- pub const FDCWD: fd_t = -2;
+ /// When linking libc, we follow their convention and use -2 for current working directory.
+ /// However, without libc, Zig does a different convention: it assumes the
+ /// current working directory is the first preopen. This behavior can be
+ /// overridden with a public function called `wasi_cwd` in the root source
+ /// file.
+ pub const FDCWD: fd_t = if (builtin.link_libc) -2 else 3;
};
// As defined in the wasi_snapshot_preview1 spec file:
lib/std/fs.zig
@@ -1488,19 +1488,7 @@ pub const Dir = struct {
/// See also `Dir.realpathZ`, `Dir.realpathW`, and `Dir.realpathAlloc`.
pub fn realpath(self: Dir, pathname: []const u8, out_buffer: []u8) ![]u8 {
if (builtin.os.tag == .wasi) {
- if (self.fd == os.wasi.AT.FDCWD or path.isAbsolute(pathname)) {
- var buffer: [MAX_PATH_BYTES]u8 = undefined;
- const out_path = try os.realpath(pathname, &buffer);
- if (out_path.len > out_buffer.len) {
- return error.NameTooLong;
- }
- mem.copy(u8, out_buffer, out_path);
- return out_buffer[0..out_path.len];
- } else {
- // Unfortunately, we have no ability to look up the path for an fd_t
- // on WASI, so we have to give up here.
- return error.InvalidHandle;
- }
+ @compileError("realpath is not available on WASI");
}
if (builtin.os.tag == .windows) {
const pathname_w = try os.windows.sliceToPrefixedFileW(pathname);
@@ -2652,8 +2640,13 @@ 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 and @hasDecl(root, "wasi_cwd")) {
- return root.wasi_cwd();
+ } else if (builtin.os.tag == .wasi) {
+ if (@hasDecl(root, "wasi_cwd")) {
+ return root.wasi_cwd();
+ } else {
+ // Expect the first preopen to be current working directory.
+ return .{ .fd = 3 };
+ }
} else {
return Dir{ .fd = os.AT.FDCWD };
}
lib/std/os.zig
@@ -2032,7 +2032,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
if (builtin.os.tag == .windows) {
@compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
} else if (builtin.os.tag == .wasi and !builtin.link_libc) {
- return symlink(mem.sliceTo(target_path, 0), mem.sliceTo(sym_link_path, 0));
+ return symlinkatZ(target_path, fs.cwd().fd, sym_link_path);
}
switch (errno(system.symlink(target_path, sym_link_path))) {
.SUCCESS => return,
@@ -2078,6 +2078,7 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c
.SUCCESS => {},
.FAULT => unreachable,
.INVAL => unreachable,
+ .BADF => unreachable,
.ACCES => return error.AccessDenied,
.PERM => return error.AccessDenied,
.DQUOT => return error.DiskQuota,