| ... | @@ -167,45 +167,6 @@ test "openat smoke test" { | ... | @@ -167,45 +167,6 @@ test "openat smoke test" { |
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | | 169 | |
| 170 | test "symlink with relative paths" { | | |
| 171 | if (native_os == .wasi) return error.SkipZigTest; // Can symlink, but can't change into tmpDir | | |
| 172 | | | |
| 173 | var tmp = tmpDir(.{}); | | |
| 174 | defer tmp.cleanup(); | | |
| 175 | | | |
| 176 | const target_name = "symlink-target"; | | |
| 177 | const symlink_name = "symlinker"; | | |
| 178 | | | |
| 179 | // Restore default CWD at end of test. | | |
| 180 | const orig_cwd = try fs.cwd().openDir(".", .{}); | | |
| 181 | defer orig_cwd.setAsCwd() catch unreachable; | | |
| 182 | | | |
| 183 | // Create the target file | | |
| 184 | try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "nonsense" }); | | |
| 185 | | | |
| 186 | // Want to test relative paths, so cd into the tmpdir for this test | | |
| 187 | try tmp.dir.setAsCwd(); | | |
| 188 | | | |
| 189 | if (native_os == .windows) { | | |
| 190 | const wtarget_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, target_name); | | |
| 191 | const wsymlink_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, symlink_name); | | |
| 192 | defer a.free(wtarget_name); | | |
| 193 | defer a.free(wsymlink_name); | | |
| 194 | | | |
| 195 | std.os.windows.CreateSymbolicLink(tmp.dir.fd, wsymlink_name, wtarget_name, false) catch |err| switch (err) { | | |
| 196 | // Symlink requires admin privileges on windows, so this test can legitimately fail. | | |
| 197 | error.AccessDenied => return error.SkipZigTest, | | |
| 198 | else => return err, | | |
| 199 | }; | | |
| 200 | } else { | | |
| 201 | try posix.symlink(target_name, symlink_name); | | |
| 202 | } | | |
| 203 | | | |
| 204 | var buffer: [fs.max_path_bytes]u8 = undefined; | | |
| 205 | const given = try posix.readlink(symlink_name, buffer[0..]); | | |
| 206 | try expect(mem.eql(u8, target_name, given)); | | |
| 207 | } | | |
| 208 | | | |
| 209 | test "readlink on Windows" { | 170 | test "readlink on Windows" { |
| 210 | if (native_os != .windows) return error.SkipZigTest; | 171 | if (native_os != .windows) return error.SkipZigTest; |
| 211 | | 172 | |
| ... | @@ -220,55 +181,6 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void { | ... | @@ -220,55 +181,6 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void { |
| 220 | try expect(mem.eql(u8, target_path, given)); | 181 | try expect(mem.eql(u8, target_path, given)); |
| 221 | } | 182 | } |
| 222 | | 183 | |
| 223 | test "link with relative paths" { | | |
| 224 | if (native_os == .wasi) return error.SkipZigTest; // Can link, but can't change into tmpDir | | |
| 225 | if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstat()`. | | |
| 226 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons. | | |
| 227 | | | |
| 228 | switch (native_os) { | | |
| 229 | .wasi, .linux, .solaris, .illumos => {}, | | |
| 230 | else => return error.SkipZigTest, | | |
| 231 | } | | |
| 232 | | | |
| 233 | var tmp = tmpDir(.{}); | | |
| 234 | defer tmp.cleanup(); | | |
| 235 | | | |
| 236 | // Restore default CWD at end of test. | | |
| 237 | const orig_cwd = try fs.cwd().openDir(".", .{}); | | |
| 238 | defer orig_cwd.setAsCwd() catch unreachable; | | |
| 239 | | | |
| 240 | const target_name = "link-target"; | | |
| 241 | const link_name = "newlink"; | | |
| 242 | | | |
| 243 | try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "example" }); | | |
| 244 | | | |
| 245 | // Test 1: create the relative link from inside tmp | | |
| 246 | try tmp.dir.setAsCwd(); | | |
| 247 | try posix.link(target_name, link_name); | | |
| 248 | | | |
| 249 | // Verify | | |
| 250 | const efd = try tmp.dir.openFile(target_name, .{}); | | |
| 251 | defer efd.close(); | | |
| 252 | | | |
| 253 | const nfd = try tmp.dir.openFile(link_name, .{}); | | |
| 254 | defer nfd.close(); | | |
| 255 | | | |
| 256 | { | | |
| 257 | const estat = try posix.fstat(efd.handle); | | |
| 258 | const nstat = try posix.fstat(nfd.handle); | | |
| 259 | try testing.expectEqual(estat.ino, nstat.ino); | | |
| 260 | try testing.expectEqual(@as(@TypeOf(nstat.nlink), 2), nstat.nlink); | | |
| 261 | } | | |
| 262 | | | |
| 263 | // Test 2: Remove the link and see the stats update | | |
| 264 | try posix.unlink(link_name); | | |
| 265 | | | |
| 266 | { | | |
| 267 | const estat = try posix.fstat(efd.handle); | | |
| 268 | try testing.expectEqual(@as(@TypeOf(estat.nlink), 1), estat.nlink); | | |
| 269 | } | | |
| 270 | } | | |
| 271 | | | |
| 272 | test "linkat with different directories" { | 184 | test "linkat with different directories" { |
| 273 | if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. | 185 | if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. |
| 274 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons. | 186 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons. |