zig/test/standalone/posix/relpaths.zig
Alex Rønne Petersen dba1bf9353 remove all Oracle Solaris support
There is no straightforward way for the Zig team to access the Solaris system
headers; to do this, one has to create an Oracle account, accept their EULA to
download the installer ISO, and finally install it on a machine or VM. We do not
have to jump through hoops like this for any other OS that we support, and no
one on the team has expressed willingness to do it.

As a result, we cannot audit any Solaris contributions to std.c or other
similarly sensitive parts of the standard library. The best we would be able to
do is assume that Solaris and illumos are 100% compatible with no way to verify
that assumption. But at that point, the solaris and illumos OS tags would be
functionally identical anyway.

For Solaris especially, any contributions that involve APIs introduced after the
OS was made closed-source would also be inherently more risky than equivalent
contributions for other proprietary OSs due to the case of Google LLC v. Oracle
America, Inc., wherein Oracle clearly demonstrated its willingness to pursue
legal action against entities that merely copy API declarations.

Finally, Oracle laid off most of the Solaris team in 2017; the OS has been in
maintenance mode since, presumably to be retired completely sometime in the 2030s.

For these reasons, this commit removes all Oracle Solaris support.

Anyone who still wishes to use Zig on Solaris can try their luck by simply using
illumos instead of solaris in target triples - chances are it'll work. But there
will be no effort from the Zig team to support this use case; we recommend that
people move to illumos instead.
2025-10-27 07:35:38 -07:00

94 lines
3.1 KiB
Zig

// Test relative paths through POSIX APIS. These tests have to change the cwd, so
// they shouldn't be Zig unit tests.
const std = @import("std");
const builtin = @import("builtin");
pub fn main() !void {
if (builtin.target.os.tag == .wasi) return; // Can link, but can't change into tmpDir
var Allocator = std.heap.DebugAllocator(.{}){};
const a = Allocator.allocator();
defer std.debug.assert(Allocator.deinit() == .ok);
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
// Want to test relative paths, so cd into the tmpdir for these tests
try tmp.dir.setAsCwd();
try test_symlink(a, tmp);
try test_link(tmp);
}
fn test_symlink(a: std.mem.Allocator, tmp: std.testing.TmpDir) !void {
const target_name = "symlink-target";
const symlink_name = "symlinker";
// Create the target file
try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "nonsense" });
if (builtin.target.os.tag == .windows) {
const wtarget_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, target_name);
const wsymlink_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, symlink_name);
defer a.free(wtarget_name);
defer a.free(wsymlink_name);
std.os.windows.CreateSymbolicLink(tmp.dir.fd, wsymlink_name, wtarget_name, false) catch |err| switch (err) {
// Symlink requires admin privileges on windows, so this test can legitimately fail.
error.AccessDenied => return,
else => return err,
};
} else {
try std.posix.symlink(target_name, symlink_name);
}
var buffer: [std.fs.max_path_bytes]u8 = undefined;
const given = try std.posix.readlink(symlink_name, buffer[0..]);
try std.testing.expectEqualStrings(target_name, given);
}
fn test_link(tmp: std.testing.TmpDir) !void {
switch (builtin.target.os.tag) {
.linux, .illumos => {},
else => return,
}
if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.target.os.tag == .linux and !builtin.link_libc) {
return; // No `fstat()`.
}
if (builtin.cpu.arch.isMIPS64()) {
return; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.
}
const target_name = "link-target";
const link_name = "newlink";
try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "example" });
// Test 1: create the relative link from inside tmp
try std.posix.link(target_name, link_name);
// Verify
const efd = try tmp.dir.openFile(target_name, .{});
defer efd.close();
const nfd = try tmp.dir.openFile(link_name, .{});
defer nfd.close();
{
const estat = try std.posix.fstat(efd.handle);
const nstat = try std.posix.fstat(nfd.handle);
try std.testing.expectEqual(estat.ino, nstat.ino);
try std.testing.expectEqual(@as(@TypeOf(nstat.nlink), 2), nstat.nlink);
}
// Test 2: Remove the link and see the stats update
try std.posix.unlink(link_name);
{
const estat = try std.posix.fstat(efd.handle);
try std.testing.expectEqual(@as(@TypeOf(estat.nlink), 1), estat.nlink);
}
}