Commit 537618464a

Andrew Kelley <andrew@ziglang.org>
2023-01-10 08:45:09
Revert "std.os: Fix std.os.chdir for WASI"
This reverts commit fff7f15fb88f6683f9d73565d8d59593ecf7461a. This commit was not intended to be cherry-picked into the 0.10.x branch.
1 parent b9ea086
Changed files (3)
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; // WASI doesn't allow navigating outside of a preopen
 
     // Get current working directory path
     var old_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
@@ -36,42 +35,16 @@ test "chdir smoke test" {
         const new_cwd = try os.getcwd(new_cwd_buf[0..]);
         try expect(mem.eql(u8, old_cwd, new_cwd));
     }
-
-    // Next, change current working directory to one level above
-    if (native_os != .wasi) { // WASI does not support navigating outside of Preopens
+    {
+        // Next, change current working directory to one level above
         const parent = fs.path.dirname(old_cwd) orelse unreachable; // old_cwd should be absolute
         try os.chdir(parent);
-
         // Restore cwd because process may have other tests that do not tolerate chdir.
         defer os.chdir(old_cwd) catch unreachable;
-
         var new_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
         const new_cwd = try os.getcwd(new_cwd_buf[0..]);
         try expect(mem.eql(u8, parent, new_cwd));
     }
-
-    // Next, change current working directory to a temp directory one level below
-    {
-        // Create a tmp directory
-        var tmp_dir_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-        var tmp_dir_path = path: {
-            var allocator = std.heap.FixedBufferAllocator.init(&tmp_dir_buf);
-            break :path try fs.path.resolve(allocator.allocator(), &[_][]const u8{ old_cwd, "zig-test-tmp" });
-        };
-        var tmp_dir = try fs.cwd().makeOpenPath("zig-test-tmp", .{});
-
-        // Change current working directory to tmp directory
-        try os.chdir("zig-test-tmp");
-
-        var new_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-        const new_cwd = try os.getcwd(new_cwd_buf[0..]);
-        try expect(mem.eql(u8, tmp_dir_path, new_cwd));
-
-        // Restore cwd because process may have other tests that do not tolerate chdir.
-        tmp_dir.close();
-        os.chdir(old_cwd) catch unreachable;
-        try fs.cwd().deleteDir("zig-test-tmp");
-    }
 }
 
 test "open smoke test" {
lib/std/os.zig
@@ -3005,19 +3005,15 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
     if (builtin.os.tag == .wasi and !builtin.link_libc) {
         var buf: [MAX_PATH_BYTES]u8 = undefined;
         var alloc = std.heap.FixedBufferAllocator.init(&buf);
-        const path = fs.path.resolve(alloc.allocator(), &.{ wasi_cwd.cwd, dir_path }) catch |err| switch (err) {
-            error.OutOfMemory => return error.NameTooLong,
-            else => |e| return e,
-        };
+        const path = try fs.resolve(alloc.allocator(), &.{ wasi_cwd.cwd, dir_path });
 
         const dirinfo = try fstatat(AT.FDCWD, path, 0);
         if (dirinfo.filetype != .DIRECTORY) {
             return error.NotDir;
         }
 
-        // This copy is guaranteed to succeed, since buf and path_buffer are the same size.
         var cwd_alloc = std.heap.FixedBufferAllocator.init(&wasi_cwd.path_buffer);
-        wasi_cwd.cwd = cwd_alloc.allocator().dupe(u8, path) catch unreachable;
+        wasi_cwd.cwd = try cwd_alloc.allocator().dupe(u8, path);
         return;
     } else if (builtin.os.tag == .windows) {
         var utf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
lib/std/testing.zig
@@ -379,13 +379,28 @@ pub const TmpIterableDir = struct {
     }
 };
 
+fn getCwdOrWasiPreopen() std.fs.Dir {
+    if (builtin.os.tag == .wasi and !builtin.link_libc) {
+        var preopens = std.fs.wasi.PreopenList.init(allocator);
+        defer preopens.deinit();
+        preopens.populate(null) catch
+            @panic("unable to make tmp dir for testing: unable to populate preopens");
+        const preopen = preopens.find(std.fs.wasi.PreopenType{ .Dir = "." }) orelse
+            @panic("unable to make tmp dir for testing: didn't find '.' in the preopens");
+
+        return std.fs.Dir{ .fd = preopen.fd };
+    } else {
+        return std.fs.cwd();
+    }
+}
+
 pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {
     var random_bytes: [TmpDir.random_bytes_count]u8 = undefined;
     std.crypto.random.bytes(&random_bytes);
     var sub_path: [TmpDir.sub_path_len]u8 = undefined;
     _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes);
 
-    var cwd = std.fs.cwd();
+    var cwd = getCwdOrWasiPreopen();
     var cache_dir = cwd.makeOpenPath("zig-cache", .{}) catch
         @panic("unable to make tmp dir for testing: unable to make and open zig-cache dir");
     defer cache_dir.close();
@@ -407,7 +422,7 @@ pub fn tmpIterableDir(opts: std.fs.Dir.OpenDirOptions) TmpIterableDir {
     var sub_path: [TmpIterableDir.sub_path_len]u8 = undefined;
     _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes);
 
-    var cwd = std.fs.cwd();
+    var cwd = getCwdOrWasiPreopen();
     var cache_dir = cwd.makeOpenPath("zig-cache", .{}) catch
         @panic("unable to make tmp dir for testing: unable to make and open zig-cache dir");
     defer cache_dir.close();