authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2024-08-05 20:24:52-07:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-09 07:41:06+01:00
logeace31c6b34037225a8331156a1faec9a2831beb
treead50e8b30a4f82c2930969a59d131f4dc2f7d245
parent02f63fdee9b7b183611cd02e98e66bbdec8ed462

std/lib: {fs,io,posix} test clean up

* use `tmp.dir.realpathAlloc()` to get full path into tmpDir instances * use `testing.allocator` where that simplifies things (vs. manual ArenaAllocator for 1 or 2 allocs) * Trust `TmpDir.cleanup()` to clean up contained files and sub-trees * Remove some unnecessary absolute paths (enabling WASI to run the tests) * Drop some no-longer necessary `[_][]const u8` casts * Add scopes to reduce `var` usage in favor of `const`

3 files changed, 223 insertions(+), 239 deletions(-)

lib/std/fs/test.zig+62-41
......@@ -320,14 +320,8 @@ test "accessAbsolute" {
320320 var tmp = tmpDir(.{});
321321 defer tmp.cleanup();
322322
323 var arena = ArenaAllocator.init(testing.allocator);
324 defer arena.deinit();
325 const allocator = arena.allocator();
326
327 const base_path = blk: {
328 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
329 break :blk try fs.realpathAlloc(allocator, relative_path);
330 };
323 const base_path = try tmp.dir.realpathAlloc(testing.allocator, ".");
324 defer testing.allocator.free(base_path);
331325
332326 try fs.accessAbsolute(base_path, .{});
333327}
......@@ -338,25 +332,52 @@ test "openDirAbsolute" {
338332 var tmp = tmpDir(.{});
339333 defer tmp.cleanup();
340334
335 const tmp_ino = (try tmp.dir.stat()).inode;
336
341337 try tmp.dir.makeDir("subdir");
342 var arena = ArenaAllocator.init(testing.allocator);
343 defer arena.deinit();
344 const allocator = arena.allocator();
338 const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir");
339 defer testing.allocator.free(sub_path);
345340
346 const base_path = blk: {
347 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..], "subdir" });
348 break :blk try fs.realpathAlloc(allocator, relative_path);
349 };
341 // Can open sub_path
342 var tmp_sub = try fs.openDirAbsolute(sub_path, .{});
343 defer tmp_sub.close();
344
345 const sub_ino = (try tmp_sub.stat()).inode;
350346
351347 {
352 var dir = try fs.openDirAbsolute(base_path, .{});
348 // Can open sub_path + ".."
349 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".." });
350 defer testing.allocator.free(dir_path);
351
352 var dir = try fs.openDirAbsolute(dir_path, .{});
353353 defer dir.close();
354
355 const ino = (try dir.stat()).inode;
356 try testing.expectEqual(tmp_ino, ino);
354357 }
355358
356 for ([_][]const u8{ ".", ".." }) |sub_path| {
357 const dir_path = try fs.path.join(allocator, &.{ base_path, sub_path });
359 {
360 // Can open sub_path + "."
361 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, "." });
362 defer testing.allocator.free(dir_path);
363
358364 var dir = try fs.openDirAbsolute(dir_path, .{});
359365 defer dir.close();
366
367 const ino = (try dir.stat()).inode;
368 try testing.expectEqual(sub_ino, ino);
369 }
370
371 {
372 // Can open subdir + "..", with some extra "."
373 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".", "..", "." });
374 defer testing.allocator.free(dir_path);
375
376 var dir = try fs.openDirAbsolute(dir_path, .{});
377 defer dir.close();
378
379 const ino = (try dir.stat()).inode;
380 try testing.expectEqual(tmp_ino, ino);
360381 }
361382}
362383
......@@ -409,10 +430,7 @@ test "readLinkAbsolute" {
409430 defer arena.deinit();
410431 const allocator = arena.allocator();
411432
412 const base_path = blk: {
413 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
414 break :blk try fs.realpathAlloc(allocator, relative_path);
415 };
433 const base_path = try tmp.dir.realpathAlloc(allocator, ".");
416434
417435 {
418436 const target_path = try fs.path.join(allocator, &.{ base_path, "file.txt" });
......@@ -748,7 +766,6 @@ test "directory operations on files" {
748766test "file operations on directories" {
749767 // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759
750768 if (native_os == .freebsd) return error.SkipZigTest;
751 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20747
752769
753770 try testWithAllSupportedPathTypes(struct {
754771 fn impl(ctx: *TestContext) !void {
......@@ -759,18 +776,30 @@ test "file operations on directories" {
759776 try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{}));
760777 try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name));
761778 switch (native_os) {
762 // no error when reading a directory.
763 .dragonfly, .netbsd => {},
764 // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
765 // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.
766 .wasi => {},
779 .dragonfly, .netbsd => {
780 // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732
781 const buf = try ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize));
782 testing.allocator.free(buf);
783 },
784 .wasi => {
785 // WASI return EBADF, which gets mapped to NotOpenForReading.
786 // See https://github.com/bytecodealliance/wasmtime/issues/1935
787 try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
788 },
767789 else => {
768790 try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
769791 },
770792 }
771 // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms.
772 // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732
773 try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }));
793
794 if (native_os == .wasi and builtin.link_libc) {
795 // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747
796 const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write });
797 handle.close();
798 } else {
799 // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms.
800 // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732
801 try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }));
802 }
774803
775804 if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) {
776805 try testing.expectError(error.IsDir, fs.createFileAbsolute(test_dir_name, .{}));
......@@ -993,10 +1022,7 @@ test "renameAbsolute" {
9931022 defer arena.deinit();
9941023 const allocator = arena.allocator();
9951024
996 const base_path = blk: {
997 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp_dir.sub_path[0..] });
998 break :blk try fs.realpathAlloc(allocator, relative_path);
999 };
1025 const base_path = try tmp_dir.dir.realpathAlloc(allocator, ".");
10001026
10011027 try testing.expectError(error.FileNotFound, fs.renameAbsolute(
10021028 try fs.path.join(allocator, &.{ base_path, "missing_file_name" }),
......@@ -1386,7 +1412,6 @@ test "sendfile" {
13861412 defer tmp.cleanup();
13871413
13881414 try tmp.dir.makePath("os_test_tmp");
1389 defer tmp.dir.deleteTree("os_test_tmp") catch {};
13901415
13911416 var dir = try tmp.dir.openDir("os_test_tmp", .{});
13921417 defer dir.close();
......@@ -1451,7 +1476,6 @@ test "copyRangeAll" {
14511476 defer tmp.cleanup();
14521477
14531478 try tmp.dir.makePath("os_test_tmp");
1454 defer tmp.dir.deleteTree("os_test_tmp") catch {};
14551479
14561480 var dir = try tmp.dir.openDir("os_test_tmp", .{});
14571481 defer dir.close();
......@@ -1800,10 +1824,7 @@ test "'.' and '..' in absolute functions" {
18001824 defer arena.deinit();
18011825 const allocator = arena.allocator();
18021826
1803 const base_path = blk: {
1804 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1805 break :blk try fs.realpathAlloc(allocator, relative_path);
1806 };
1827 const base_path = try tmp.dir.realpathAlloc(allocator, ".");
18071828
18081829 const subdir_path = try fs.path.join(allocator, &.{ base_path, "./subdir" });
18091830 try fs.makeDirAbsolute(subdir_path);
lib/std/io/test.zig+4-12
......@@ -108,10 +108,7 @@ test "File seek ops" {
108108
109109 const tmp_file_name = "temp_test_file.txt";
110110 var file = try tmp.dir.createFile(tmp_file_name, .{});
111 defer {
112 file.close();
113 tmp.dir.deleteFile(tmp_file_name) catch {};
114 }
111 defer file.close();
115112
116113 try file.writeAll(&([_]u8{0x55} ** 8192));
117114
......@@ -135,10 +132,7 @@ test "setEndPos" {
135132
136133 const tmp_file_name = "temp_test_file.txt";
137134 var file = try tmp.dir.createFile(tmp_file_name, .{});
138 defer {
139 file.close();
140 tmp.dir.deleteFile(tmp_file_name) catch {};
141 }
135 defer file.close();
142136
143137 // Verify that the file size changes and the file offset is not moved
144138 try std.testing.expect((try file.getEndPos()) == 0);
......@@ -161,10 +155,8 @@ test "updateTimes" {
161155
162156 const tmp_file_name = "just_a_temporary_file.txt";
163157 var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true });
164 defer {
165 file.close();
166 tmp.dir.deleteFile(tmp_file_name) catch {};
167 }
158 defer file.close();
159
168160 const stat_old = try file.stat();
169161 // Set atime and mtime to 5s before
170162 try file.updateTimes(
lib/std/posix/test.zig+157-186
......@@ -8,7 +8,6 @@ const io = std.io;
88const fs = std.fs;
99const mem = std.mem;
1010const elf = std.elf;
11const File = std.fs.File;
1211const Thread = std.Thread;
1312const linux = std.os.linux;
1413
......@@ -19,8 +18,6 @@ const AtomicRmwOp = std.builtin.AtomicRmwOp;
1918const AtomicOrder = std.builtin.AtomicOrder;
2019const native_os = builtin.target.os.tag;
2120const tmpDir = std.testing.tmpDir;
22const Dir = std.fs.Dir;
23const ArenaAllocator = std.heap.ArenaAllocator;
2421
2522// https://github.com/ziglang/zig/issues/20288
2623test "WTF-8 to WTF-16 conversion buffer overflows" {
......@@ -115,50 +112,62 @@ test "open smoke test" {
115112 var tmp = tmpDir(.{});
116113 defer tmp.cleanup();
117114
118 // Get base abs path
119 var arena = ArenaAllocator.init(testing.allocator);
120 defer arena.deinit();
121 const allocator = arena.allocator();
115 const base_path = try tmp.dir.realpathAlloc(a, ".");
116 defer a.free(base_path);
122117
123 const base_path = blk: {
124 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
125 break :blk try fs.realpathAlloc(allocator, relative_path);
126 };
127
128 var file_path: []u8 = undefined;
129 var fd: posix.fd_t = undefined;
130118 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
131119
132 // Create some file using `open`.
133 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
134 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
135 posix.close(fd);
120 {
121 // Create some file using `open`.
122 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
123 defer a.free(file_path);
124 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
125 posix.close(fd);
126 }
136127
137 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
138 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
139 try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));
128 {
129 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
130 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
131 defer a.free(file_path);
132 try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));
133 }
140134
141 // Try opening without `EXCL` flag.
142 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
143 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);
144 posix.close(fd);
135 {
136 // Try opening without `EXCL` flag.
137 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
138 defer a.free(file_path);
139 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);
140 posix.close(fd);
141 }
145142
146 // Try opening as a directory which should fail.
147 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
148 try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));
143 {
144 // Try opening as a directory which should fail.
145 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
146 defer a.free(file_path);
147 try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));
148 }
149149
150 // Create some directory
151 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
152 try posix.mkdir(file_path, mode);
150 {
151 // Create some directory
152 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
153 defer a.free(file_path);
154 try posix.mkdir(file_path, mode);
155 }
153156
154 // Open dir using `open`
155 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
156 fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
157 posix.close(fd);
157 {
158 // Open dir using `open`
159 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
160 defer a.free(file_path);
161 const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
162 posix.close(fd);
163 }
158164
159 // Try opening as file which should fail.
160 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
161 try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
165 {
166 // Try opening as file which should fail.
167 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
168 defer a.free(file_path);
169 try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
170 }
162171}
163172
164173test "openat smoke test" {
......@@ -705,8 +714,6 @@ test "mmap" {
705714 try testing.expectEqual(i, try stream.readInt(u32, .little));
706715 }
707716 }
708
709 try tmp.dir.deleteFile(test_out_file);
710717}
711718
712719test "getenv" {
......@@ -732,10 +739,7 @@ test "fcntl" {
732739 const test_out_file = "os_tmp_test";
733740
734741 const file = try tmp.dir.createFile(test_out_file, .{});
735 defer {
736 file.close();
737 tmp.dir.deleteFile(test_out_file) catch {};
738 }
742 defer file.close();
739743
740744 // Note: The test assumes createFile opens the file with CLOEXEC
741745 {
......@@ -771,10 +775,7 @@ test "sync" {
771775
772776 const test_out_file = "os_tmp_test";
773777 const file = try tmp.dir.createFile(test_out_file, .{});
774 defer {
775 file.close();
776 tmp.dir.deleteFile(test_out_file) catch {};
777 }
778 defer file.close();
778779
779780 posix.sync();
780781 try posix.syncfs(file.handle);
......@@ -791,10 +792,7 @@ test "fsync" {
791792
792793 const test_out_file = "os_tmp_test";
793794 const file = try tmp.dir.createFile(test_out_file, .{});
794 defer {
795 file.close();
796 tmp.dir.deleteFile(test_out_file) catch {};
797 }
795 defer file.close();
798796
799797 try posix.fsync(file.handle);
800798 try posix.fdatasync(file.handle);
......@@ -1041,54 +1039,65 @@ test "rename smoke test" {
10411039 var tmp = tmpDir(.{});
10421040 defer tmp.cleanup();
10431041
1044 // Get base abs path
1045 var arena = ArenaAllocator.init(testing.allocator);
1046 defer arena.deinit();
1047 const allocator = arena.allocator();
1048
1049 const base_path = blk: {
1050 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1051 break :blk try fs.realpathAlloc(allocator, relative_path);
1052 };
1042 const base_path = try tmp.dir.realpathAlloc(a, ".");
1043 defer a.free(base_path);
10531044
1054 var file_path: []u8 = undefined;
1055 var fd: posix.fd_t = undefined;
10561045 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
10571046
1058 // Create some file using `open`.
1059 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1060 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1061 posix.close(fd);
1062
1063 // Rename the file
1064 var new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
1065 try posix.rename(file_path, new_file_path);
1066
1067 // Try opening renamed file
1068 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
1069 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode);
1070 posix.close(fd);
1047 {
1048 // Create some file using `open`.
1049 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1050 defer a.free(file_path);
1051 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1052 posix.close(fd);
1053
1054 // Rename the file
1055 const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1056 defer a.free(new_file_path);
1057 try posix.rename(file_path, new_file_path);
1058 }
10711059
1072 // Try opening original file - should fail with error.FileNotFound
1073 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1074 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
1060 {
1061 // Try opening renamed file
1062 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1063 defer a.free(file_path);
1064 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode);
1065 posix.close(fd);
1066 }
10751067
1076 // Create some directory
1077 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
1078 try posix.mkdir(file_path, mode);
1068 {
1069 // Try opening original file - should fail with error.FileNotFound
1070 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1071 defer a.free(file_path);
1072 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
1073 }
10791074
1080 // Rename the directory
1081 new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });
1082 try posix.rename(file_path, new_file_path);
1075 {
1076 // Create some directory
1077 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1078 defer a.free(file_path);
1079 try posix.mkdir(file_path, mode);
1080
1081 // Rename the directory
1082 const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" });
1083 defer a.free(new_file_path);
1084 try posix.rename(file_path, new_file_path);
1085 }
10831086
1084 // Try opening renamed directory
1085 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });
1086 fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
1087 posix.close(fd);
1087 {
1088 // Try opening renamed directory
1089 const file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" });
1090 defer a.free(file_path);
1091 const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
1092 posix.close(fd);
1093 }
10881094
1089 // Try opening original directory - should fail with error.FileNotFound
1090 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
1091 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));
1095 {
1096 // Try opening original directory - should fail with error.FileNotFound
1097 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1098 defer a.free(file_path);
1099 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));
1100 }
10921101}
10931102
10941103test "access smoke test" {
......@@ -1098,44 +1107,50 @@ test "access smoke test" {
10981107 var tmp = tmpDir(.{});
10991108 defer tmp.cleanup();
11001109
1101 // Get base abs path
1102 var arena = ArenaAllocator.init(testing.allocator);
1103 defer arena.deinit();
1104 const allocator = arena.allocator();
1105
1106 const base_path = blk: {
1107 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1108 break :blk try fs.realpathAlloc(allocator, relative_path);
1109 };
1110 const base_path = try tmp.dir.realpathAlloc(a, ".");
1111 defer a.free(base_path);
11101112
1111 var file_path: []u8 = undefined;
1112 var fd: posix.fd_t = undefined;
11131113 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
1114 {
1115 // Create some file using `open`.
1116 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1117 defer a.free(file_path);
1118 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1119 posix.close(fd);
1120 }
11141121
1115 // Create some file using `open`.
1116 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1117 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1118 posix.close(fd);
1122 {
1123 // Try to access() the file
1124 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1125 defer a.free(file_path);
1126 if (native_os == .windows) {
1127 try posix.access(file_path, posix.F_OK);
1128 } else {
1129 try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);
1130 }
1131 }
11191132
1120 // Try to access() the file
1121 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1122 if (native_os == .windows) {
1123 try posix.access(file_path, posix.F_OK);
1124 } else {
1125 try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);
1133 {
1134 // Try to access() a non-existent file - should fail with error.FileNotFound
1135 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1136 defer a.free(file_path);
1137 try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));
11261138 }
11271139
1128 // Try to access() a non-existent file - should fail with error.FileNotFound
1129 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
1130 try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));
1140 {
1141 // Create some directory
1142 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1143 defer a.free(file_path);
1144 try posix.mkdir(file_path, mode);
1145 }
11311146
1132 // Create some directory
1133 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
1134 try posix.mkdir(file_path, mode);
1147 {
1148 // Try to access() the directory
1149 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1150 defer a.free(file_path);
11351151
1136 // Try to access() the directory
1137 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
1138 try posix.access(file_path, posix.F_OK);
1152 try posix.access(file_path, posix.F_OK);
1153 }
11391154}
11401155
11411156test "timerfd" {
......@@ -1167,103 +1182,59 @@ test "isatty" {
11671182}
11681183
11691184test "read with empty buffer" {
1170 if (native_os == .wasi) return error.SkipZigTest;
1171
11721185 var tmp = tmpDir(.{});
11731186 defer tmp.cleanup();
11741187
1175 var arena = ArenaAllocator.init(testing.allocator);
1176 defer arena.deinit();
1177 const allocator = arena.allocator();
1178
1179 // Get base abs path
1180 const base_path = blk: {
1181 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1182 break :blk try fs.realpathAlloc(allocator, relative_path);
1183 };
1184
1185 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1186 var file = try fs.cwd().createFile(file_path, .{ .read = true });
1188 var file = try tmp.dir.createFile("read_empty", .{ .read = true });
11871189 defer file.close();
11881190
1189 const bytes = try allocator.alloc(u8, 0);
1191 const bytes = try a.alloc(u8, 0);
1192 defer a.free(bytes);
11901193
1191 _ = try posix.read(file.handle, bytes);
1194 const rc = try posix.read(file.handle, bytes);
1195 try expectEqual(rc, 0);
11921196}
11931197
11941198test "pread with empty buffer" {
1195 if (native_os == .wasi) return error.SkipZigTest;
1196
11971199 var tmp = tmpDir(.{});
11981200 defer tmp.cleanup();
11991201
1200 var arena = ArenaAllocator.init(testing.allocator);
1201 defer arena.deinit();
1202 const allocator = arena.allocator();
1203
1204 // Get base abs path
1205 const base_path = blk: {
1206 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1207 break :blk try fs.realpathAlloc(allocator, relative_path);
1208 };
1209
1210 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1211 var file = try fs.cwd().createFile(file_path, .{ .read = true });
1202 var file = try tmp.dir.createFile("pread_empty", .{ .read = true });
12121203 defer file.close();
12131204
1214 const bytes = try allocator.alloc(u8, 0);
1205 const bytes = try a.alloc(u8, 0);
1206 defer a.free(bytes);
12151207
1216 _ = try posix.pread(file.handle, bytes, 0);
1208 const rc = try posix.pread(file.handle, bytes, 0);
1209 try expectEqual(rc, 0);
12171210}
12181211
12191212test "write with empty buffer" {
1220 if (native_os == .wasi) return error.SkipZigTest;
1221
12221213 var tmp = tmpDir(.{});
12231214 defer tmp.cleanup();
12241215
1225 var arena = ArenaAllocator.init(testing.allocator);
1226 defer arena.deinit();
1227 const allocator = arena.allocator();
1228
1229 // Get base abs path
1230 const base_path = blk: {
1231 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1232 break :blk try fs.realpathAlloc(allocator, relative_path);
1233 };
1234
1235 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1236 var file = try fs.cwd().createFile(file_path, .{});
1216 var file = try tmp.dir.createFile("write_empty", .{});
12371217 defer file.close();
12381218
1239 const bytes = try allocator.alloc(u8, 0);
1219 const bytes = try a.alloc(u8, 0);
1220 defer a.free(bytes);
12401221
1241 _ = try posix.write(file.handle, bytes);
1222 const rc = try posix.write(file.handle, bytes);
1223 try expectEqual(rc, 0);
12421224}
12431225
12441226test "pwrite with empty buffer" {
1245 if (native_os == .wasi) return error.SkipZigTest;
1246
12471227 var tmp = tmpDir(.{});
12481228 defer tmp.cleanup();
12491229
1250 var arena = ArenaAllocator.init(testing.allocator);
1251 defer arena.deinit();
1252 const allocator = arena.allocator();
1253
1254 // Get base abs path
1255 const base_path = blk: {
1256 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1257 break :blk try fs.realpathAlloc(allocator, relative_path);
1258 };
1259
1260 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1261 var file = try fs.cwd().createFile(file_path, .{});
1230 var file = try tmp.dir.createFile("pwrite_empty", .{});
12621231 defer file.close();
12631232
1264 const bytes = try allocator.alloc(u8, 0);
1233 const bytes = try a.alloc(u8, 0);
1234 defer a.free(bytes);
12651235
1266 _ = try posix.pwrite(file.handle, bytes, 0);
1236 const rc = try posix.pwrite(file.handle, bytes, 0);
1237 try expectEqual(rc, 0);
12671238}
12681239
12691240fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void {