mirror of
https://github.com/ziglang/zig.git
synced 2026-02-17 14:59:14 +00:00
commit
3869e80331
@ -74,7 +74,6 @@ pub extern "c" fn exit(code: c_int) noreturn;
|
||||
pub extern "c" fn isatty(fd: fd_t) c_int;
|
||||
pub extern "c" fn close(fd: fd_t) c_int;
|
||||
pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
|
||||
pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
|
||||
pub extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int;
|
||||
pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t;
|
||||
pub extern "c" fn open(path: [*:0]const u8, oflag: c_uint, ...) c_int;
|
||||
@ -185,6 +184,7 @@ pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;
|
||||
pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;
|
||||
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
|
||||
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
|
||||
pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int;
|
||||
pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
|
||||
pub extern "c" fn pthread_self() pthread_t;
|
||||
pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
|
||||
|
||||
@ -13,6 +13,7 @@ pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize;
|
||||
pub extern "c" fn _dyld_get_image_name(image_index: u32) [*:0]const u8;
|
||||
|
||||
pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;
|
||||
pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
|
||||
|
||||
pub extern "c" fn mach_absolute_time() u64;
|
||||
pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
const std = @import("../std.zig");
|
||||
const builtin = std.builtin;
|
||||
|
||||
usingnamespace std.c;
|
||||
|
||||
extern "c" fn __errno() *c_int;
|
||||
pub const _errno = __errno;
|
||||
|
||||
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
|
||||
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
|
||||
|
||||
pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int;
|
||||
pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int;
|
||||
pub extern "c" fn __clock_getres50(clk_id: c_int, tp: *timespec) c_int;
|
||||
pub extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int;
|
||||
pub extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
||||
pub const pthread_mutex_t = extern struct {
|
||||
ptm_magic: c_uint = 0x33330003,
|
||||
|
||||
@ -654,6 +654,8 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
|
||||
switch (builtin.os.tag) {
|
||||
.linux,
|
||||
.freebsd,
|
||||
.netbsd,
|
||||
.dragonfly,
|
||||
.macosx,
|
||||
.windows,
|
||||
=> return DebugInfo.init(allocator),
|
||||
@ -1047,7 +1049,7 @@ const MachoSymbol = struct {
|
||||
|
||||
fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
|
||||
noasync {
|
||||
const file = try fs.openFileAbsolute(path, .{ .always_blocking = true });
|
||||
const file = try fs.cwd().openFile(path, .{ .always_blocking = true });
|
||||
defer file.close();
|
||||
|
||||
const file_len = try math.cast(usize, try file.getEndPos());
|
||||
@ -1621,7 +1623,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
|
||||
};
|
||||
}
|
||||
},
|
||||
.linux, .freebsd => struct {
|
||||
.linux, .netbsd, .freebsd, .dragonfly => struct {
|
||||
base_address: usize,
|
||||
dwarf: DW.DwarfInfo,
|
||||
mapped_memory: []const u8,
|
||||
|
||||
@ -339,12 +339,10 @@ pub const Dir = struct {
|
||||
fn nextBsd(self: *Self) !?Entry {
|
||||
start_over: while (true) {
|
||||
if (self.index >= self.end_index) {
|
||||
const rc = os.system.getdirentries(
|
||||
self.dir.fd,
|
||||
&self.buf,
|
||||
self.buf.len,
|
||||
&self.seek,
|
||||
);
|
||||
const rc = if (builtin.os.tag == .netbsd)
|
||||
os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len)
|
||||
else
|
||||
os.system.getdents(self.dir.fd, &self.buf, self.buf.len);
|
||||
switch (os.errno(rc)) {
|
||||
0 => {},
|
||||
os.EBADF => unreachable, // Dir is invalid or was opened without iteration ability
|
||||
|
||||
@ -2531,18 +2531,15 @@ pub const FStatError = error{
|
||||
|
||||
pub fn fstat(fd: fd_t) FStatError!Stat {
|
||||
var stat: Stat = undefined;
|
||||
if (comptime std.Target.current.isDarwin()) {
|
||||
switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {
|
||||
0 => return stat,
|
||||
EINVAL => unreachable,
|
||||
EBADF => unreachable, // Always a race condition.
|
||||
ENOMEM => return error.SystemResources,
|
||||
EACCES => return error.AccessDenied,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
switch (errno(system.fstat(fd, &stat))) {
|
||||
const symbol_name = if (comptime std.Target.current.isDarwin())
|
||||
"fstat$INODE64"
|
||||
else if (std.Target.current.os.tag == .netbsd)
|
||||
"__fstat50"
|
||||
else
|
||||
"fstat";
|
||||
|
||||
switch (errno(@field(system, symbol_name)(fd, &stat))) {
|
||||
0 => return stat,
|
||||
EINVAL => unreachable,
|
||||
EBADF => unreachable, // Always a race condition.
|
||||
@ -3401,7 +3398,13 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (errno(system.clock_gettime(clk_id, tp))) {
|
||||
|
||||
const symbol_name = if (std.Target.current.os.tag == .netbsd)
|
||||
"__clock_gettime50"
|
||||
else
|
||||
"clock_gettime";
|
||||
|
||||
switch (errno(@field(system, symbol_name)(clk_id, tp))) {
|
||||
0 => return,
|
||||
EFAULT => unreachable,
|
||||
EINVAL => return error.UnsupportedClock,
|
||||
@ -3423,7 +3426,12 @@ pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (errno(system.clock_getres(clk_id, res))) {
|
||||
const symbol_name = if (std.Target.current.os.tag == .netbsd)
|
||||
"__clock_getres50"
|
||||
else
|
||||
"clock_getres";
|
||||
|
||||
switch (errno(@field(system, symbol_name)(clk_id, res))) {
|
||||
0 => return,
|
||||
EFAULT => unreachable,
|
||||
EINVAL => return error.UnsupportedClock,
|
||||
@ -3489,10 +3497,12 @@ pub const SigaltstackError = error{
|
||||
} || UnexpectedError;
|
||||
|
||||
pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
|
||||
if (builtin.os.tag == .windows or builtin.os.tag == .uefi or builtin.os.tag == .wasi)
|
||||
@compileError("std.os.sigaltstack not available for this target");
|
||||
const symbol_name = if (std.Target.current.os.tag == .netbsd)
|
||||
"__sigaltstack14"
|
||||
else
|
||||
"sigaltstack";
|
||||
|
||||
switch (errno(system.sigaltstack(ss, old_ss))) {
|
||||
switch (errno(@field(system, symbol_name)(ss, old_ss))) {
|
||||
0 => return,
|
||||
EFAULT => unreachable,
|
||||
EINVAL => unreachable,
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
const std = @import("../../std.zig");
|
||||
const maxInt = std.math.maxInt;
|
||||
|
||||
pub const fd_t = c_int;
|
||||
pub const pid_t = c_int;
|
||||
pub const mode_t = c_uint;
|
||||
pub const fd_t = i32;
|
||||
pub const pid_t = i32;
|
||||
pub const mode_t = u32;
|
||||
pub const ino_t = u64;
|
||||
pub const off_t = i64;
|
||||
pub const socklen_t = u32;
|
||||
|
||||
/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
|
||||
pub const Kevent = extern struct {
|
||||
@ -22,6 +25,65 @@ pub const dl_phdr_info = extern struct {
|
||||
dlpi_phnum: u16,
|
||||
};
|
||||
|
||||
pub const addrinfo = extern struct {
|
||||
flags: i32,
|
||||
family: i32,
|
||||
socktype: i32,
|
||||
protocol: i32,
|
||||
addrlen: socklen_t,
|
||||
canonname: ?[*:0]u8,
|
||||
addr: ?*sockaddr,
|
||||
next: ?*addrinfo,
|
||||
};
|
||||
|
||||
pub const EAI = extern enum(c_int) {
|
||||
/// address family for hostname not supported
|
||||
ADDRFAMILY = 1,
|
||||
|
||||
/// name could not be resolved at this time
|
||||
AGAIN = 2,
|
||||
|
||||
/// flags parameter had an invalid value
|
||||
BADFLAGS = 3,
|
||||
|
||||
/// non-recoverable failure in name resolution
|
||||
FAIL = 4,
|
||||
|
||||
/// address family not recognized
|
||||
FAMILY = 5,
|
||||
|
||||
/// memory allocation failure
|
||||
MEMORY = 6,
|
||||
|
||||
/// no address associated with hostname
|
||||
NODATA = 7,
|
||||
|
||||
/// name does not resolve
|
||||
NONAME = 8,
|
||||
|
||||
/// service not recognized for socket type
|
||||
SERVICE = 9,
|
||||
|
||||
/// intended socket type was not recognized
|
||||
SOCKTYPE = 10,
|
||||
|
||||
/// system error returned in errno
|
||||
SYSTEM = 11,
|
||||
|
||||
/// invalid value for hints
|
||||
BADHINTS = 12,
|
||||
|
||||
/// resolved protocol is unknown
|
||||
PROTOCOL = 13,
|
||||
|
||||
/// argument buffer overflow
|
||||
OVERFLOW = 14,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
pub const EAI_MAX = 15;
|
||||
|
||||
pub const msghdr = extern struct {
|
||||
/// optional address
|
||||
msg_name: ?*sockaddr,
|
||||
@ -68,9 +130,6 @@ pub const msghdr_const = extern struct {
|
||||
msg_flags: i32,
|
||||
};
|
||||
|
||||
pub const off_t = i64;
|
||||
pub const ino_t = u64;
|
||||
|
||||
/// Renamed to Stat to not conflict with the stat function.
|
||||
/// atime, mtime, and ctime have functions to return `timespec`,
|
||||
/// because although this is a POSIX API, the layout and names of
|
||||
@ -122,7 +181,6 @@ pub const dirent = extern struct {
|
||||
d_reclen: u16,
|
||||
d_namlen: u16,
|
||||
d_type: u8,
|
||||
d_off: i64,
|
||||
d_name: [512]u8,
|
||||
|
||||
pub fn reclen(self: dirent) u16 {
|
||||
@ -146,7 +204,7 @@ pub const sockaddr = extern struct {
|
||||
|
||||
pub const sockaddr_in = extern struct {
|
||||
len: u8 = @sizeOf(sockaddr_in),
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_INET,
|
||||
port: in_port_t,
|
||||
addr: u32,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
@ -154,7 +212,7 @@ pub const sockaddr_in = extern struct {
|
||||
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
len: u8 = @sizeOf(sockaddr_in6),
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_INET6,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
addr: [16]u8,
|
||||
@ -167,12 +225,27 @@ pub const sockaddr_un = extern struct {
|
||||
len: u8 = @sizeOf(sockaddr_un),
|
||||
|
||||
/// AF_LOCAL
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_LOCAL,
|
||||
|
||||
/// path name
|
||||
path: [104]u8,
|
||||
};
|
||||
|
||||
/// get address to use bind()
|
||||
pub const AI_PASSIVE = 0x00000001;
|
||||
|
||||
/// fill ai_canonname
|
||||
pub const AI_CANONNAME = 0x00000002;
|
||||
|
||||
/// prevent host name resolution
|
||||
pub const AI_NUMERICHOST = 0x00000004;
|
||||
|
||||
/// prevent service name resolution
|
||||
pub const AI_NUMERICSERV = 0x00000008;
|
||||
|
||||
/// only if any address is assigned
|
||||
pub const AI_ADDRCONFIG = 0x00000400;
|
||||
|
||||
pub const CTL_KERN = 1;
|
||||
pub const CTL_DEBUG = 5;
|
||||
|
||||
@ -274,30 +347,71 @@ pub const X_OK = 1; // test for execute or search permission
|
||||
pub const W_OK = 2; // test for write permission
|
||||
pub const R_OK = 4; // test for read permission
|
||||
|
||||
pub const O_RDONLY = 0x0000;
|
||||
pub const O_WRONLY = 0x0001;
|
||||
pub const O_RDWR = 0x0002;
|
||||
pub const O_ACCMODE = 0x0003;
|
||||
/// open for reading only
|
||||
pub const O_RDONLY = 0x00000000;
|
||||
|
||||
pub const O_CREAT = 0x0200;
|
||||
pub const O_EXCL = 0x0800;
|
||||
pub const O_NOCTTY = 0x8000;
|
||||
pub const O_TRUNC = 0x0400;
|
||||
pub const O_APPEND = 0x0008;
|
||||
pub const O_NONBLOCK = 0x0004;
|
||||
pub const O_DSYNC = 0x00010000;
|
||||
pub const O_SYNC = 0x0080;
|
||||
pub const O_RSYNC = 0x00020000;
|
||||
pub const O_DIRECTORY = 0x00080000;
|
||||
/// open for writing only
|
||||
pub const O_WRONLY = 0x00000001;
|
||||
|
||||
/// open for reading and writing
|
||||
pub const O_RDWR = 0x00000002;
|
||||
|
||||
/// mask for above modes
|
||||
pub const O_ACCMODE = 0x00000003;
|
||||
|
||||
/// no delay
|
||||
pub const O_NONBLOCK = 0x00000004;
|
||||
|
||||
/// set append mode
|
||||
pub const O_APPEND = 0x00000008;
|
||||
|
||||
/// open with shared file lock
|
||||
pub const O_SHLOCK = 0x00000010;
|
||||
|
||||
/// open with exclusive file lock
|
||||
pub const O_EXLOCK = 0x00000020;
|
||||
|
||||
/// signal pgrp when data ready
|
||||
pub const O_ASYNC = 0x00000040;
|
||||
|
||||
/// synchronous writes
|
||||
pub const O_SYNC = 0x00000080;
|
||||
|
||||
/// don't follow symlinks on the last
|
||||
pub const O_NOFOLLOW = 0x00000100;
|
||||
|
||||
/// create if nonexistent
|
||||
pub const O_CREAT = 0x00000200;
|
||||
|
||||
/// truncate to zero length
|
||||
pub const O_TRUNC = 0x00000400;
|
||||
|
||||
/// error if already exists
|
||||
pub const O_EXCL = 0x00000800;
|
||||
|
||||
/// don't assign controlling terminal
|
||||
pub const O_NOCTTY = 0x00008000;
|
||||
|
||||
/// write: I/O data completion
|
||||
pub const O_DSYNC = 0x00010000;
|
||||
|
||||
/// read: I/O completion as for write
|
||||
pub const O_RSYNC = 0x00020000;
|
||||
|
||||
/// use alternate i/o semantics
|
||||
pub const O_ALT_IO = 0x00040000;
|
||||
|
||||
/// direct I/O hint
|
||||
pub const O_DIRECT = 0x00080000;
|
||||
|
||||
/// fail if not a directory
|
||||
pub const O_DIRECTORY = 0x00200000;
|
||||
|
||||
/// set close on exec
|
||||
pub const O_CLOEXEC = 0x00400000;
|
||||
|
||||
pub const O_ASYNC = 0x0040;
|
||||
pub const O_DIRECT = 0x00080000;
|
||||
pub const O_NOATIME = 0;
|
||||
pub const O_PATH = 0;
|
||||
pub const O_TMPFILE = 0;
|
||||
pub const O_NDELAY = O_NONBLOCK;
|
||||
/// skip search permission checks
|
||||
pub const O_SEARCH = 0x00800000;
|
||||
|
||||
pub const F_DUPFD = 0;
|
||||
pub const F_GETFD = 1;
|
||||
@ -816,6 +930,23 @@ pub fn S_IWHT(m: u32) bool {
|
||||
return m & S_IFMT == S_IFWHT;
|
||||
}
|
||||
|
||||
/// Magic value that specify the use of the current working directory
|
||||
/// to determine the target of relative file paths in the openat() and
|
||||
/// similar syscalls.
|
||||
pub const AT_FDCWD = -100;
|
||||
|
||||
/// Check access using effective user and group ID
|
||||
pub const AT_EACCESS = 0x0100;
|
||||
|
||||
/// Do not follow symbolic links
|
||||
pub const AT_SYMLINK_NOFOLLOW = 0x0200;
|
||||
|
||||
/// Follow symbolic link
|
||||
pub const AT_SYMLINK_FOLLOW = 0x0400;
|
||||
|
||||
/// Remove directory instead of file
|
||||
pub const AT_REMOVEDIR = 0x0800;
|
||||
|
||||
pub const HOST_NAME_MAX = 255;
|
||||
|
||||
/// dummy for IP
|
||||
|
||||
@ -292,32 +292,69 @@ pub const Thread = struct {
|
||||
l += tls_img.alloc_size;
|
||||
}
|
||||
}
|
||||
break :blk l;
|
||||
// Round the size to the page size.
|
||||
break :blk mem.alignForward(l, mem.page_size);
|
||||
};
|
||||
// Map the whole stack with no rw permissions to avoid committing the
|
||||
// whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mem.alignForward(mmap_len, mem.page_size),
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
const mmap_slice = mem: {
|
||||
if (std.Target.current.os.tag != .netbsd) {
|
||||
// Map the whole stack with no rw permissions to avoid
|
||||
// committing the whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice[guard_end_offset..],
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
} else {
|
||||
// NetBSD mprotect is very strict and doesn't allow to "upgrade"
|
||||
// a PROT_NONE mapping to a RW one so let's allocate everything
|
||||
// right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Remap the guard page with no permissions
|
||||
os.mprotect(
|
||||
mmap_slice[0..guard_end_offset],
|
||||
os.PROT_NONE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
}
|
||||
};
|
||||
|
||||
const mmap_addr = @ptrToInt(mmap_slice.ptr);
|
||||
@ -338,7 +375,17 @@ pub const Thread = struct {
|
||||
if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;
|
||||
defer assert(c.pthread_attr_destroy(&attr) == 0);
|
||||
|
||||
assert(c.pthread_attr_setstack(&attr, mmap_slice.ptr, stack_end_offset) == 0);
|
||||
// Tell pthread where the effective stack start is and its size
|
||||
assert(c.pthread_attr_setstack(
|
||||
&attr,
|
||||
mmap_slice.ptr + guard_end_offset,
|
||||
stack_end_offset - guard_end_offset,
|
||||
) == 0);
|
||||
// Even though pthread's man pages state that the guard size is
|
||||
// ignored when the stack address is explicitly given, on some
|
||||
// plaforms such as NetBSD we still have to zero it to prevent
|
||||
// random crashes in pthread_join calls
|
||||
assert(c.pthread_attr_setguardsize(&attr, 0) == 0);
|
||||
|
||||
const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
|
||||
switch (err) {
|
||||
|
||||
@ -1799,7 +1799,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
lj->args.append("-lm");
|
||||
}
|
||||
|
||||
if (g->zig_target->os == OsFreeBSD) {
|
||||
if (g->zig_target->os == OsFreeBSD ||
|
||||
g->zig_target->os == OsNetBSD)
|
||||
{
|
||||
lj->args.append("-lpthread");
|
||||
}
|
||||
} else if (target_is_glibc(g->zig_target)) {
|
||||
|
||||
@ -1161,9 +1161,6 @@ Error os_update_file(Buf *src_path, Buf *dst_path) {
|
||||
fclose(dst_libc_file);
|
||||
return err;
|
||||
}
|
||||
if (fflush(src_libc_file) == -1) {
|
||||
return ErrorUnexpected;
|
||||
}
|
||||
if (fflush(dst_libc_file) == -1) {
|
||||
return ErrorUnexpected;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user