| ... | ... | @@ -8,7 +8,6 @@ const io = std.io; |
| 8 | 8 | const fs = std.fs; |
| 9 | 9 | const mem = std.mem; |
| 10 | 10 | const elf = std.elf; |
| 11 | | const File = std.fs.File; |
| 12 | 11 | const Thread = std.Thread; |
| 13 | 12 | const linux = std.os.linux; |
| 14 | 13 | |
| ... | ... | @@ -19,8 +18,6 @@ const AtomicRmwOp = std.builtin.AtomicRmwOp; |
| 19 | 18 | const AtomicOrder = std.builtin.AtomicOrder; |
| 20 | 19 | const native_os = builtin.target.os.tag; |
| 21 | 20 | const tmpDir = std.testing.tmpDir; |
| 22 | | const Dir = std.fs.Dir; |
| 23 | | const ArenaAllocator = std.heap.ArenaAllocator; |
| 24 | 21 | |
| 25 | 22 | // https://github.com/ziglang/zig/issues/20288 |
| 26 | 23 | test "WTF-8 to WTF-16 conversion buffer overflows" { |
| ... | ... | @@ -115,50 +112,62 @@ test "open smoke test" { |
| 115 | 112 | var tmp = tmpDir(.{}); |
| 116 | 113 | defer tmp.cleanup(); |
| 117 | 114 | |
| 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); |
| 122 | 117 | |
| 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; |
| 130 | 118 | const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; |
| 131 | 119 | |
| 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 | } |
| 136 | 127 | |
| 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 | } |
| 140 | 134 | |
| 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 | } |
| 145 | 142 | |
| 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 | } |
| 149 | 149 | |
| 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 | } |
| 153 | 156 | |
| 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 | } |
| 158 | 164 | |
| 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 | } |
| 162 | 171 | } |
| 163 | 172 | |
| 164 | 173 | test "openat smoke test" { |
| ... | ... | @@ -705,8 +714,6 @@ test "mmap" { |
| 705 | 714 | try testing.expectEqual(i, try stream.readInt(u32, .little)); |
| 706 | 715 | } |
| 707 | 716 | } |
| 708 | | |
| 709 | | try tmp.dir.deleteFile(test_out_file); |
| 710 | 717 | } |
| 711 | 718 | |
| 712 | 719 | test "getenv" { |
| ... | ... | @@ -732,10 +739,7 @@ test "fcntl" { |
| 732 | 739 | const test_out_file = "os_tmp_test"; |
| 733 | 740 | |
| 734 | 741 | 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(); |
| 739 | 743 | |
| 740 | 744 | // Note: The test assumes createFile opens the file with CLOEXEC |
| 741 | 745 | { |
| ... | ... | @@ -771,10 +775,7 @@ test "sync" { |
| 771 | 775 | |
| 772 | 776 | const test_out_file = "os_tmp_test"; |
| 773 | 777 | 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(); |
| 778 | 779 | |
| 779 | 780 | posix.sync(); |
| 780 | 781 | try posix.syncfs(file.handle); |
| ... | ... | @@ -791,10 +792,7 @@ test "fsync" { |
| 791 | 792 | |
| 792 | 793 | const test_out_file = "os_tmp_test"; |
| 793 | 794 | 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(); |
| 798 | 796 | |
| 799 | 797 | try posix.fsync(file.handle); |
| 800 | 798 | try posix.fdatasync(file.handle); |
| ... | ... | @@ -1041,54 +1039,65 @@ test "rename smoke test" { |
| 1041 | 1039 | var tmp = tmpDir(.{}); |
| 1042 | 1040 | defer tmp.cleanup(); |
| 1043 | 1041 | |
| 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); |
| 1053 | 1044 | |
| 1054 | | var file_path: []u8 = undefined; |
| 1055 | | var fd: posix.fd_t = undefined; |
| 1056 | 1045 | const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; |
| 1057 | 1046 | |
| 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 | } |
| 1071 | 1059 | |
| 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 | } |
| 1075 | 1067 | |
| 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 | } |
| 1079 | 1074 | |
| 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 | } |
| 1083 | 1086 | |
| 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 | } |
| 1088 | 1094 | |
| 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 | } |
| 1092 | 1101 | } |
| 1093 | 1102 | |
| 1094 | 1103 | test "access smoke test" { |
| ... | ... | @@ -1098,44 +1107,50 @@ test "access smoke test" { |
| 1098 | 1107 | var tmp = tmpDir(.{}); |
| 1099 | 1108 | defer tmp.cleanup(); |
| 1100 | 1109 | |
| 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); |
| 1110 | 1112 | |
| 1111 | | var file_path: []u8 = undefined; |
| 1112 | | var fd: posix.fd_t = undefined; |
| 1113 | 1113 | 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 | } |
| 1114 | 1121 | |
| 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 | } |
| 1119 | 1132 | |
| 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)); |
| 1126 | 1138 | } |
| 1127 | 1139 | |
| 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 | } |
| 1131 | 1146 | |
| 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); |
| 1135 | 1151 | |
| 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 | } |
| 1139 | 1154 | } |
| 1140 | 1155 | |
| 1141 | 1156 | test "timerfd" { |
| ... | ... | @@ -1167,103 +1182,59 @@ test "isatty" { |
| 1167 | 1182 | } |
| 1168 | 1183 | |
| 1169 | 1184 | test "read with empty buffer" { |
| 1170 | | if (native_os == .wasi) return error.SkipZigTest; |
| 1171 | | |
| 1172 | 1185 | var tmp = tmpDir(.{}); |
| 1173 | 1186 | defer tmp.cleanup(); |
| 1174 | 1187 | |
| 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 }); |
| 1187 | 1189 | defer file.close(); |
| 1188 | 1190 | |
| 1189 | | const bytes = try allocator.alloc(u8, 0); |
| 1191 | const bytes = try a.alloc(u8, 0); |
| 1192 | defer a.free(bytes); |
| 1190 | 1193 | |
| 1191 | | _ = try posix.read(file.handle, bytes); |
| 1194 | const rc = try posix.read(file.handle, bytes); |
| 1195 | try expectEqual(rc, 0); |
| 1192 | 1196 | } |
| 1193 | 1197 | |
| 1194 | 1198 | test "pread with empty buffer" { |
| 1195 | | if (native_os == .wasi) return error.SkipZigTest; |
| 1196 | | |
| 1197 | 1199 | var tmp = tmpDir(.{}); |
| 1198 | 1200 | defer tmp.cleanup(); |
| 1199 | 1201 | |
| 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 }); |
| 1212 | 1203 | defer file.close(); |
| 1213 | 1204 | |
| 1214 | | const bytes = try allocator.alloc(u8, 0); |
| 1205 | const bytes = try a.alloc(u8, 0); |
| 1206 | defer a.free(bytes); |
| 1215 | 1207 | |
| 1216 | | _ = try posix.pread(file.handle, bytes, 0); |
| 1208 | const rc = try posix.pread(file.handle, bytes, 0); |
| 1209 | try expectEqual(rc, 0); |
| 1217 | 1210 | } |
| 1218 | 1211 | |
| 1219 | 1212 | test "write with empty buffer" { |
| 1220 | | if (native_os == .wasi) return error.SkipZigTest; |
| 1221 | | |
| 1222 | 1213 | var tmp = tmpDir(.{}); |
| 1223 | 1214 | defer tmp.cleanup(); |
| 1224 | 1215 | |
| 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", .{}); |
| 1237 | 1217 | defer file.close(); |
| 1238 | 1218 | |
| 1239 | | const bytes = try allocator.alloc(u8, 0); |
| 1219 | const bytes = try a.alloc(u8, 0); |
| 1220 | defer a.free(bytes); |
| 1240 | 1221 | |
| 1241 | | _ = try posix.write(file.handle, bytes); |
| 1222 | const rc = try posix.write(file.handle, bytes); |
| 1223 | try expectEqual(rc, 0); |
| 1242 | 1224 | } |
| 1243 | 1225 | |
| 1244 | 1226 | test "pwrite with empty buffer" { |
| 1245 | | if (native_os == .wasi) return error.SkipZigTest; |
| 1246 | | |
| 1247 | 1227 | var tmp = tmpDir(.{}); |
| 1248 | 1228 | defer tmp.cleanup(); |
| 1249 | 1229 | |
| 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", .{}); |
| 1262 | 1231 | defer file.close(); |
| 1263 | 1232 | |
| 1264 | | const bytes = try allocator.alloc(u8, 0); |
| 1233 | const bytes = try a.alloc(u8, 0); |
| 1234 | defer a.free(bytes); |
| 1265 | 1235 | |
| 1266 | | _ = try posix.pwrite(file.handle, bytes, 0); |
| 1236 | const rc = try posix.pwrite(file.handle, bytes, 0); |
| 1237 | try expectEqual(rc, 0); |
| 1267 | 1238 | } |
| 1268 | 1239 | |
| 1269 | 1240 | fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void { |