Initial bringup of the Solaris/Illumos port

This commit is contained in:
Stephen Gregoratto 2021-08-31 22:21:23 +10:00 committed by Andrew Kelley
parent a032fd01e8
commit 87fd502fb6
20 changed files with 2148 additions and 55 deletions

View File

@ -41,6 +41,7 @@ pub const max_name_len = switch (target.os.tag) {
.netbsd => 31,
.freebsd => 15,
.openbsd => 31,
.solaris => 31,
else => 0,
};
@ -112,7 +113,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
else => |e| return os.unexpectedErrno(e),
}
},
.netbsd => if (use_pthreads) {
.netbsd, .solaris => if (use_pthreads) {
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null);
switch (err) {
.SUCCESS => return,
@ -202,7 +203,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
else => |e| return os.unexpectedErrno(e),
}
},
.netbsd => if (use_pthreads) {
.netbsd, .solaris => if (use_pthreads) {
const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1);
switch (err) {
.SUCCESS => return std.mem.sliceTo(buffer, 0),
@ -565,6 +566,16 @@ const PosixThreadImpl = struct {
};
return @intCast(usize, count);
},
.solaris => {
// The "proper" way to get the cpu count would be to query
// /dev/kstat via ioctls, and traverse a linked list for each
// cpu.
const rc = c.sysconf(os._SC.NPROCESSORS_ONLN);
return switch (os.errno(rc)) {
.SUCCESS => @intCast(usize, rc),
else => |err| os.unexpectedErrno(err),
};
},
.haiku => {
var count: u32 = undefined;
var system_info: os.system_info = undefined;

View File

@ -252,6 +252,33 @@ pub extern "c" fn kevent(
timeout: ?*const c.timespec,
) c_int;
pub extern "c" fn port_create() c.port_t;
pub extern "c" fn port_associate(
port: c.port_t,
source: u32,
object: usize,
events: u32,
user_var: ?*c_void,
) c_int;
pub extern "c" fn port_dissociate(port: c.port_t, source: u32, object: usize) c_int;
pub extern "c" fn port_send(port: c.port_t, events: u32, user_var: ?*c_void) c_int;
pub extern "c" fn port_sendn(
ports: [*]c.port_t,
errors: []u32,
num_ports: u32,
events: u32,
user_var: ?*c_void,
) c_int;
pub extern "c" fn port_get(port: c.port_t, event: *c.port_event, timeout: ?*c.timespec) c_int;
pub extern "c" fn port_getn(
port: c.port_t,
event_list: []c.port_event,
max_events: u32,
events_retrieved: *u32,
timeout: ?*c.timespec,
) c_int;
pub extern "c" fn port_alert(port: c.port_t, flags: u32, events: u32, user_var: ?*c_void) c_int;
pub extern "c" fn getaddrinfo(
noalias node: ?[*:0]const u8,
noalias service: ?[*:0]const u8,

File diff suppressed because it is too large Load Diff

View File

@ -654,6 +654,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
.openbsd,
.macos,
.windows,
.solaris,
=> return DebugInfo.init(allocator),
else => return error.UnsupportedDebugInfo,
}
@ -1420,7 +1421,7 @@ pub const ModuleDebugInfo = switch (native_os) {
};
}
},
.linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku => struct {
.linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris => struct {
base_address: usize,
dwarf: DW.DwarfInfo,
mapped_memory: []const u8,
@ -1468,7 +1469,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
/// Whether or not the current target can print useful debug information when a segfault occurs.
pub const have_segfault_handling_support = switch (native_os) {
.linux, .netbsd => true,
.linux, .netbsd, .solaris => true,
.windows => true,
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
else => false,
@ -1535,6 +1536,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
.freebsd => @ptrToInt(info.addr),
.netbsd => @ptrToInt(info.info.reason.fault.addr),
.openbsd => @ptrToInt(info.data.fault.addr),
.solaris => @ptrToInt(info.reason.fault.addr),
else => unreachable,
};
@ -1559,13 +1561,13 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
.x86_64 => {
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
const ip = switch (native_os) {
.linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
.freebsd => @intCast(usize, ctx.mcontext.rip),
.openbsd => @intCast(usize, ctx.sc_rip),
else => unreachable,
};
const bp = switch (native_os) {
.linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
.openbsd => @intCast(usize, ctx.sc_rbp),
.freebsd => @intCast(usize, ctx.mcontext.rbp),
else => unreachable,

View File

@ -14,7 +14,7 @@ const max = std.math.max;
pub const DynLib = switch (builtin.os.tag) {
.linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
.windows => WindowsDynLib,
.macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly => DlDynlib,
.macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly, .solaris => DlDynlib,
else => void,
};

View File

@ -35,7 +35,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
/// fit into a UTF-8 encoded array of this length.
/// The byte count includes room for a null sentinel byte.
pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => os.PATH_MAX,
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku, .solaris => os.PATH_MAX,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
// If it would require 4 UTF-8 bytes, then there would be a surrogate
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@ -298,10 +298,10 @@ pub const Dir = struct {
pub const Kind = File.Kind;
};
const IteratorError = error{AccessDenied} || os.UnexpectedError;
const IteratorError = error{ AccessDenied, SystemResources } || os.UnexpectedError;
pub const Iterator = switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => struct {
dir: Dir,
seek: i64,
buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)),
@ -318,6 +318,7 @@ pub const Dir = struct {
switch (builtin.os.tag) {
.macos, .ios => return self.nextDarwin(),
.freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
.solaris => return self.nextSolaris(),
else => @compileError("unimplemented"),
}
}
@ -372,6 +373,60 @@ pub const Dir = struct {
}
}
fn nextSolaris(self: *Self) !?Entry {
start_over: while (true) {
if (self.index >= self.end_index) {
const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len);
switch (os.errno(rc)) {
.SUCCESS => {},
.BADF => unreachable, // Dir is invalid or was opened without iteration ability
.FAULT => unreachable,
.NOTDIR => unreachable,
.INVAL => unreachable,
else => |err| return os.unexpectedErrno(err),
}
if (rc == 0) return null;
self.index = 0;
self.end_index = @intCast(usize, rc);
}
const entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
const next_index = self.index + entry.reclen();
self.index = next_index;
const name = mem.spanZ(@ptrCast([*:0]u8, &entry.d_name));
if (mem.eql(u8, name, ".") or mem.eql(u8, name, ".."))
continue :start_over;
// Solaris dirent doesn't expose d_type, so we have to call stat to get it.
const stat_info = os.fstatat(
self.dir.fd,
name,
os.AT.SYMLINK_NOFOLLOW,
) catch |err| switch (err) {
error.NameTooLong => unreachable,
error.SymLinkLoop => unreachable,
error.FileNotFound => unreachable, // lost the race
else => |e| return e,
};
const entry_kind = switch (stat_info.mode & os.S.IFMT) {
os.S.IFIFO => Entry.Kind.NamedPipe,
os.S.IFCHR => Entry.Kind.CharacterDevice,
os.S.IFDIR => Entry.Kind.Directory,
os.S.IFBLK => Entry.Kind.BlockDevice,
os.S.IFREG => Entry.Kind.File,
os.S.IFLNK => Entry.Kind.SymLink,
os.S.IFSOCK => Entry.Kind.UnixDomainSocket,
os.S.IFDOOR => Entry.Kind.Door,
os.S.IFPORT => Entry.Kind.EventPort,
else => Entry.Kind.Unknown,
};
return Entry{
.name = name,
.kind = entry_kind,
};
}
}
fn nextBsd(self: *Self) !?Entry {
start_over: while (true) {
if (self.index >= self.end_index) {
@ -704,6 +759,7 @@ pub const Dir = struct {
.netbsd,
.dragonfly,
.openbsd,
.solaris,
=> return Iterator{
.dir = self,
.seek = 0,
@ -1556,7 +1612,7 @@ pub const Dir = struct {
error.AccessDenied => |e| switch (builtin.os.tag) {
// non-Linux POSIX systems return EPERM when trying to delete a directory, so
// we need to handle that case specifically and translate the error
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
// Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT.SYMLINK_NOFOLLOW) catch return e;
const is_dir = fstat.mode & os.S.IFMT == os.S.IFDIR;
@ -2441,6 +2497,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
}
switch (builtin.os.tag) {
.linux => return os.readlinkZ("/proc/self/exe", out_buffer),
.solaris => return os.readlinkZ("/proc/self/path/a.out", out_buffer),
.freebsd, .dragonfly => {
var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
var out_len: usize = out_buffer.len;

View File

@ -41,6 +41,8 @@ pub const File = struct {
File,
UnixDomainSocket,
Whiteout,
Door,
EventPort,
Unknown,
};
@ -320,28 +322,40 @@ pub const File = struct {
const atime = st.atime();
const mtime = st.mtime();
const ctime = st.ctime();
const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {
.BLOCK_DEVICE => Kind.BlockDevice,
.CHARACTER_DEVICE => Kind.CharacterDevice,
.DIRECTORY => Kind.Directory,
.SYMBOLIC_LINK => Kind.SymLink,
.REGULAR_FILE => Kind.File,
.SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket,
else => Kind.Unknown,
} else blk: {
const m = st.mode & os.S.IFMT;
switch (m) {
os.S.IFBLK => break :blk Kind.BlockDevice,
os.S.IFCHR => break :blk Kind.CharacterDevice,
os.S.IFDIR => break :blk Kind.Directory,
os.S.IFIFO => break :blk Kind.NamedPipe,
os.S.IFLNK => break :blk Kind.SymLink,
os.S.IFREG => break :blk Kind.File,
os.S.IFSOCK => break :blk Kind.UnixDomainSocket,
else => {},
}
if (builtin.os.tag == .solaris) switch (m) {
os.S.IFDOOR => break :blk Kind.Door,
os.S.IFPORT => break :blk Kind.EventPort,
else => {},
};
break :blk .Unknown;
};
return Stat{
.inode = st.ino,
.size = @bitCast(u64, st.size),
.mode = st.mode,
.kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {
.BLOCK_DEVICE => Kind.BlockDevice,
.CHARACTER_DEVICE => Kind.CharacterDevice,
.DIRECTORY => Kind.Directory,
.SYMBOLIC_LINK => Kind.SymLink,
.REGULAR_FILE => Kind.File,
.SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket,
else => Kind.Unknown,
} else switch (st.mode & os.S.IFMT) {
os.S.IFBLK => Kind.BlockDevice,
os.S.IFCHR => Kind.CharacterDevice,
os.S.IFDIR => Kind.Directory,
os.S.IFIFO => Kind.NamedPipe,
os.S.IFLNK => Kind.SymLink,
os.S.IFREG => Kind.File,
os.S.IFSOCK => Kind.UnixDomainSocket,
else => Kind.Unknown,
},
.kind = kind,
.atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
.mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
.ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,

View File

@ -44,7 +44,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
},
.linux, .freebsd, .netbsd, .dragonfly, .openbsd => {
.linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
const home_dir = os.getenv("HOME") orelse {
// TODO look in /etc/passwd
return error.AppDataDirUnavailable;

View File

@ -188,7 +188,7 @@ fn contains(entries: *const std.ArrayList(Dir.Entry), el: Dir.Entry) bool {
test "Dir.realpath smoke test" {
switch (builtin.os.tag) {
.linux, .windows, .macos, .ios, .watchos, .tvos => {},
.linux, .windows, .macos, .ios, .watchos, .tvos, .solaris => {},
else => return error.SkipZigTest,
}

View File

@ -31,6 +31,7 @@ pub const freebsd = std.c;
pub const haiku = std.c;
pub const netbsd = std.c;
pub const openbsd = std.c;
pub const solaris = std.c;
pub const linux = @import("os/linux.zig");
pub const uefi = @import("os/uefi.zig");
pub const wasi = @import("os/wasi.zig");
@ -64,8 +65,10 @@ else switch (builtin.os.tag) {
};
pub const AF = system.AF;
pub const AF_SUN = system.AF_SUN;
pub const ARCH = system.ARCH;
pub const AT = system.AT;
pub const AT_SUN = system.AT_SUN;
pub const CLOCK = system.CLOCK;
pub const CPU_COUNT = system.CPU_COUNT;
pub const CTL = system.CTL;
@ -101,6 +104,7 @@ pub const RR = system.RR;
pub const S = system.S;
pub const SA = system.SA;
pub const SC = system.SC;
pub const _SC = system._SC;
pub const SEEK = system.SEEK;
pub const SHUT = system.SHUT;
pub const SIG = system.SIG;
@ -143,6 +147,10 @@ pub const off_t = system.off_t;
pub const oflags_t = system.oflags_t;
pub const pid_t = system.pid_t;
pub const pollfd = system.pollfd;
pub const port_t = system.port_t;
pub const port_event = system.port_event;
pub const port_notify = system.port_notify;
pub const file_obj = system.file_obj;
pub const rights_t = system.rights_t;
pub const rlim_t = system.rlim_t;
pub const rlimit = system.rlimit;
@ -2038,6 +2046,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr
.NOTDIR => return error.NotDir,
.NOMEM => return error.SystemResources,
.ROFS => return error.ReadOnlyFileSystem,
.EXIST => return error.DirNotEmpty,
.NOTEMPTY => return error.DirNotEmpty,
.INVAL => unreachable, // invalid flags, or pathname has . as last component
@ -4667,6 +4676,16 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
};
return target;
},
.solaris => {
var procfs_buf: ["/proc/self/path/-2147483648".len:0]u8 = undefined;
const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable;
const target = readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
error.UnsupportedReparsePointType => unreachable,
else => |e| return e,
};
return target;
},
else => @compileError("querying for canonical path of a handle is unsupported on this host"),
}
}

View File

@ -188,7 +188,10 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
}
test "link with relative paths" {
if (native_os != .linux) return error.SkipZigTest;
switch (native_os) {
.linux, .solaris => {},
else => return error.SkipZigTest,
}
var cwd = fs.cwd();
cwd.deleteFile("example.txt") catch {};
@ -222,7 +225,10 @@ test "link with relative paths" {
}
test "linkat with different directories" {
if (native_os != .linux) return error.SkipZigTest;
switch (native_os) {
.linux, .solaris => {},
else => return error.SkipZigTest,
}
var cwd = fs.cwd();
var tmp = tmpDir(.{});
@ -634,8 +640,10 @@ test "fcntl" {
}
test "signalfd" {
if (native_os != .linux)
return error.SkipZigTest;
switch (native_os) {
.linux, .solaris => {},
else => return error.SkipZigTest,
}
_ = std.os.signalfd;
}
@ -658,8 +666,10 @@ test "sync" {
}
test "fsync" {
if (native_os != .linux and native_os != .windows)
return error.SkipZigTest;
switch (native_os) {
.linux, .windows, .solaris => {},
else => return error.SkipZigTest,
}
var tmp = tmpDir(.{});
defer tmp.cleanup();
@ -754,7 +764,10 @@ test "sigaction" {
}
test "dup & dup2" {
if (native_os != .linux) return error.SkipZigTest;
switch (native_os) {
.linux, .solaris => {},
else => return error.SkipZigTest,
}
var tmp = tmpDir(.{});
defer tmp.cleanup();

View File

@ -625,7 +625,7 @@ pub const UserInfo = struct {
/// POSIX function which gets a uid from username.
pub fn getUserInfo(name: []const u8) !UserInfo {
return switch (builtin.os.tag) {
.linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku => posixGetUserInfo(name),
.linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku, .solaris => posixGetUserInfo(name),
else => @compileError("Unsupported OS"),
};
}
@ -753,6 +753,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
.netbsd,
.dragonfly,
.openbsd,
.solaris,
=> {
var paths = List.init(allocator);
errdefer {

View File

@ -235,7 +235,6 @@ pub const Target = struct {
.fuchsia,
.kfreebsd,
.lv2,
.solaris,
.zos,
.haiku,
.minix,
@ -310,6 +309,12 @@ pub const Target = struct {
.max = .{ .major = 6, .minor = 0 },
},
},
.solaris => return .{
.semver = .{
.min = .{ .major = 5, .minor = 11 },
.max = .{ .major = 5, .minor = 11 },
},
},
.linux => return .{
.linux = .{
@ -353,6 +358,7 @@ pub const Target = struct {
.netbsd,
.openbsd,
.dragonfly,
.solaris,
=> return TaggedVersionRange{ .semver = self.version_range.semver },
else => return .none,
@ -385,6 +391,7 @@ pub const Target = struct {
.dragonfly,
.openbsd,
.haiku,
.solaris,
=> true,
.linux,
@ -395,7 +402,6 @@ pub const Target = struct {
.fuchsia,
.kfreebsd,
.lv2,
.solaris,
.zos,
.minix,
.rtems,
@ -1516,6 +1522,7 @@ pub const Target = struct {
.netbsd => return copy(&result, "/libexec/ld.elf_so"),
.openbsd => return copy(&result, "/usr/libexec/ld.so"),
.dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
.solaris => return copy(&result, "/lib/64/ld.so.1"),
.linux => switch (self.cpu.arch) {
.i386,
.sparc,
@ -1634,7 +1641,6 @@ pub const Target = struct {
.fuchsia,
.kfreebsd,
.lv2,
.solaris,
.zos,
.minix,
.rtems,

View File

@ -101,6 +101,17 @@ pub const NativePaths = struct {
return self;
}
if (comptime native_target.os.tag == .solaris) {
try self.addLibDir("/usr/lib/64");
try self.addLibDir("/usr/local/lib/64");
try self.addLibDir("/lib/64");
try self.addIncludeDir("/usr/include");
try self.addIncludeDir("/usr/local/include");
return self;
}
if (native_target.os.tag != .windows) {
const triple = try native_target.linuxTriple(allocator);
const qual = native_target.cpu.arch.ptrBitWidth();
@ -243,6 +254,18 @@ pub const NativeTargetInfo = struct {
error.InvalidVersion => {},
}
},
.solaris => {
const uts = std.os.uname();
const release = mem.spanZ(&uts.release);
if (std.builtin.Version.parse(release)) |ver| {
os.version_range.semver.min = ver;
os.version_range.semver.max = ver;
} else |err| switch (err) {
error.Overflow => {},
error.InvalidCharacter => {},
error.InvalidVersion => {},
}
},
.windows => {
const detected_version = windows.detectRuntimeVersion();
os.version_range.windows.min = detected_version;

View File

@ -221,6 +221,7 @@ pub const LibCInstallation = struct {
batch.add(&async self.findNativeIncludeDirPosix(args));
switch (Target.current.os.tag) {
.freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
.solaris => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib/64"),
.linux => batch.add(&async self.findNativeCrtDirPosix(args)),
else => {},
}

View File

@ -3446,6 +3446,15 @@ const CsuObjects = struct {
.static_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
// zig fmt: on
},
.solaris => switch (mode) {
// zig fmt: off
.dynamic_lib => result.set( null, "crti.o", null, null, "crtn.o" ),
.dynamic_exe,
.dynamic_pie => result.set( "crt1.o", "crti.o", null, null, "crtn.o" ),
.static_exe,
.static_pie => result.set( null, null, null, null, null ),
// zig fmt: on
},
else => {},
}
}

View File

@ -33,6 +33,8 @@
#define ZIG_OS_OPENBSD
#elif defined(__HAIKU__)
#define ZIG_OS_HAIKU
#elif defined(__sun)
#define ZIG_OS_SOLARIS
#else
#define ZIG_OS_UNKNOWN
#endif

View File

@ -399,6 +399,9 @@ Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
#elif defined(ZIG_OS_HAIKU)
*out_os = OsHaiku;
return ErrorNone;
#elif defined(ZIG_OS_SOLARIS)
*out_os = OsSolaris;
return ErrorNone;
#else
zig_panic("stage1 is unable to detect native target for this OS");
#endif
@ -670,6 +673,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsOpenBSD:
case OsWASI:
case OsHaiku:
case OsSolaris:
case OsEmscripten:
case OsPlan9:
switch (id) {
@ -728,7 +732,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsCloudABI:
case OsKFreeBSD:
case OsLv2:
case OsSolaris:
case OsZOS:
case OsMinix:
case OsRTEMS:

View File

@ -433,6 +433,13 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
"-lc",
"-lutil",
},
.solaris => &[_][]const u8{
"-lm",
"-lsocket",
"-lnsl",
// Solaris releases after 10 merged the threading libraries into libc.
"-lc",
},
.haiku => &[_][]const u8{
"-lm",
"-lroot",

View File

@ -3800,6 +3800,7 @@ pub const CType = enum {
.wasi,
.emscripten,
.plan9,
.solaris,
=> switch (self) {
.short,
.ushort,
@ -3851,7 +3852,6 @@ pub const CType = enum {
.fuchsia,
.kfreebsd,
.lv2,
.solaris,
.zos,
.haiku,
.minix,