std: fix WASI regressions
This branch largely reverts 58f961f4cb. I
would like to revisit the proposal to modify the standard library in
this way and think more carefully about it before adding isAbsolute()
checks everywhere.
This commit is contained in:
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user