| author | |
| committer | |
| log | 3869e803318721134170ca8e90190cdfbadbe475 |
| tree | 5d5282ad4be25d465275a93df202a61faed3b361 |
| parent | 778dbc17acce77588a46a27074ecb8b418786d94 |
| parent | 3ccf99c0bd5a681c56c456d1606b5eccfcf31fb7 |
| signature |
Netbsd forever10 files changed, 283 insertions(+), 87 deletions(-)
lib/std/c.zig+1-1| ... | ... | @@ -74,7 +74,6 @@ pub extern "c" fn exit(code: c_int) noreturn; |
| 74 | 74 | pub extern "c" fn isatty(fd: fd_t) c_int; |
| 75 | 75 | pub extern "c" fn close(fd: fd_t) c_int; |
| 76 | 76 | pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int; |
| 77 | pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int; | |
| 78 | 77 | pub extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int; |
| 79 | 78 | pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t; |
| 80 | 79 | 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; |
| 185 | 184 | 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; |
| 186 | 185 | pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int; |
| 187 | 186 | pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int; |
| 187 | pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int; | |
| 188 | 188 | pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int; |
| 189 | 189 | pub extern "c" fn pthread_self() pthread_t; |
| 190 | 190 | pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int; |
lib/std/c/darwin.zig+1| ... | ... | @@ -13,6 +13,7 @@ pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize; |
| 13 | 13 | pub extern "c" fn _dyld_get_image_name(image_index: u32) [*:0]const u8; |
| 14 | 14 | |
| 15 | 15 | pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize; |
| 16 | pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int; | |
| 16 | 17 | |
| 17 | 18 | pub extern "c" fn mach_absolute_time() u64; |
| 18 | 19 | pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void; |
lib/std/c/netbsd.zig+10-2| ... | ... | @@ -1,11 +1,19 @@ |
| 1 | 1 | const std = @import("../std.zig"); |
| 2 | const builtin = std.builtin; | |
| 3 | ||
| 2 | 4 | usingnamespace std.c; |
| 3 | 5 | |
| 4 | 6 | extern "c" fn __errno() *c_int; |
| 5 | 7 | pub const _errno = __errno; |
| 6 | 8 | |
| 7 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; | |
| 8 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | |
| 9 | pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int; | |
| 10 | pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; | |
| 11 | ||
| 12 | pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int; | |
| 13 | pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int; | |
| 14 | pub extern "c" fn __clock_getres50(clk_id: c_int, tp: *timespec) c_int; | |
| 15 | pub extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int; | |
| 16 | pub extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | |
| 9 | 17 | |
| 10 | 18 | pub const pthread_mutex_t = extern struct { |
| 11 | 19 | ptm_magic: c_uint = 0x33330003, |
lib/std/debug.zig+4-2| ... | ... | @@ -654,6 +654,8 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo { |
| 654 | 654 | switch (builtin.os.tag) { |
| 655 | 655 | .linux, |
| 656 | 656 | .freebsd, |
| 657 | .netbsd, | |
| 658 | .dragonfly, | |
| 657 | 659 | .macosx, |
| 658 | 660 | .windows, |
| 659 | 661 | => return DebugInfo.init(allocator), |
| ... | ... | @@ -1047,7 +1049,7 @@ const MachoSymbol = struct { |
| 1047 | 1049 | |
| 1048 | 1050 | fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 { |
| 1049 | 1051 | noasync { |
| 1050 | const file = try fs.openFileAbsolute(path, .{ .always_blocking = true }); | |
| 1052 | const file = try fs.cwd().openFile(path, .{ .always_blocking = true }); | |
| 1051 | 1053 | defer file.close(); |
| 1052 | 1054 | |
| 1053 | 1055 | const file_len = try math.cast(usize, try file.getEndPos()); |
| ... | ... | @@ -1621,7 +1623,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) { |
| 1621 | 1623 | }; |
| 1622 | 1624 | } |
| 1623 | 1625 | }, |
| 1624 | .linux, .freebsd => struct { | |
| 1626 | .linux, .netbsd, .freebsd, .dragonfly => struct { | |
| 1625 | 1627 | base_address: usize, |
| 1626 | 1628 | dwarf: DW.DwarfInfo, |
| 1627 | 1629 | mapped_memory: []const u8, |
lib/std/fs.zig+4-6| ... | ... | @@ -339,12 +339,10 @@ pub const Dir = struct { |
| 339 | 339 | fn nextBsd(self: *Self) !?Entry { |
| 340 | 340 | start_over: while (true) { |
| 341 | 341 | if (self.index >= self.end_index) { |
| 342 | const rc = os.system.getdirentries( | |
| 343 | self.dir.fd, | |
| 344 | &self.buf, | |
| 345 | self.buf.len, | |
| 346 | &self.seek, | |
| 347 | ); | |
| 342 | const rc = if (builtin.os.tag == .netbsd) | |
| 343 | os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len) | |
| 344 | else | |
| 345 | os.system.getdents(self.dir.fd, &self.buf, self.buf.len); | |
| 348 | 346 | switch (os.errno(rc)) { |
| 349 | 347 | 0 => {}, |
| 350 | 348 | os.EBADF => unreachable, // Dir is invalid or was opened without iteration ability |
lib/std/os.zig+26-16| ... | ... | @@ -2531,18 +2531,15 @@ pub const FStatError = error{ |
| 2531 | 2531 | |
| 2532 | 2532 | pub fn fstat(fd: fd_t) FStatError!Stat { |
| 2533 | 2533 | var stat: Stat = undefined; |
| 2534 | if (comptime std.Target.current.isDarwin()) { | |
| 2535 | switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) { | |
| 2536 | 0 => return stat, | |
| 2537 | EINVAL => unreachable, | |
| 2538 | EBADF => unreachable, // Always a race condition. | |
| 2539 | ENOMEM => return error.SystemResources, | |
| 2540 | EACCES => return error.AccessDenied, | |
| 2541 | else => |err| return unexpectedErrno(err), | |
| 2542 | } | |
| 2543 | } | |
| 2544 | 2534 | |
| 2545 | switch (errno(system.fstat(fd, &stat))) { | |
| 2535 | const symbol_name = if (comptime std.Target.current.isDarwin()) | |
| 2536 | "fstat$INODE64" | |
| 2537 | else if (std.Target.current.os.tag == .netbsd) | |
| 2538 | "__fstat50" | |
| 2539 | else | |
| 2540 | "fstat"; | |
| 2541 | ||
| 2542 | switch (errno(@field(system, symbol_name)(fd, &stat))) { | |
| 2546 | 2543 | 0 => return stat, |
| 2547 | 2544 | EINVAL => unreachable, |
| 2548 | 2545 | EBADF => unreachable, // Always a race condition. |
| ... | ... | @@ -3401,7 +3398,13 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { |
| 3401 | 3398 | } |
| 3402 | 3399 | return; |
| 3403 | 3400 | } |
| 3404 | switch (errno(system.clock_gettime(clk_id, tp))) { | |
| 3401 | ||
| 3402 | const symbol_name = if (std.Target.current.os.tag == .netbsd) | |
| 3403 | "__clock_gettime50" | |
| 3404 | else | |
| 3405 | "clock_gettime"; | |
| 3406 | ||
| 3407 | switch (errno(@field(system, symbol_name)(clk_id, tp))) { | |
| 3405 | 3408 | 0 => return, |
| 3406 | 3409 | EFAULT => unreachable, |
| 3407 | 3410 | EINVAL => return error.UnsupportedClock, |
| ... | ... | @@ -3423,7 +3426,12 @@ pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void { |
| 3423 | 3426 | return; |
| 3424 | 3427 | } |
| 3425 | 3428 | |
| 3426 | switch (errno(system.clock_getres(clk_id, res))) { | |
| 3429 | const symbol_name = if (std.Target.current.os.tag == .netbsd) | |
| 3430 | "__clock_getres50" | |
| 3431 | else | |
| 3432 | "clock_getres"; | |
| 3433 | ||
| 3434 | switch (errno(@field(system, symbol_name)(clk_id, res))) { | |
| 3427 | 3435 | 0 => return, |
| 3428 | 3436 | EFAULT => unreachable, |
| 3429 | 3437 | EINVAL => return error.UnsupportedClock, |
| ... | ... | @@ -3489,10 +3497,12 @@ pub const SigaltstackError = error{ |
| 3489 | 3497 | } || UnexpectedError; |
| 3490 | 3498 | |
| 3491 | 3499 | pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { |
| 3492 | if (builtin.os.tag == .windows or builtin.os.tag == .uefi or builtin.os.tag == .wasi) | |
| 3493 | @compileError("std.os.sigaltstack not available for this target"); | |
| 3500 | const symbol_name = if (std.Target.current.os.tag == .netbsd) | |
| 3501 | "__sigaltstack14" | |
| 3502 | else | |
| 3503 | "sigaltstack"; | |
| 3494 | 3504 | |
| 3495 | switch (errno(system.sigaltstack(ss, old_ss))) { | |
| 3505 | switch (errno(@field(system, symbol_name)(ss, old_ss))) { | |
| 3496 | 3506 | 0 => return, |
| 3497 | 3507 | EFAULT => unreachable, |
| 3498 | 3508 | EINVAL => unreachable, |
lib/std/os/bits/netbsd.zig+161-30| ... | ... | @@ -1,9 +1,12 @@ |
| 1 | 1 | const std = @import("../../std.zig"); |
| 2 | 2 | const maxInt = std.math.maxInt; |
| 3 | 3 | |
| 4 | pub const fd_t = c_int; | |
| 5 | pub const pid_t = c_int; | |
| 6 | pub const mode_t = c_uint; | |
| 4 | pub const fd_t = i32; | |
| 5 | pub const pid_t = i32; | |
| 6 | pub const mode_t = u32; | |
| 7 | pub const ino_t = u64; | |
| 8 | pub const off_t = i64; | |
| 9 | pub const socklen_t = u32; | |
| 7 | 10 | |
| 8 | 11 | /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. |
| 9 | 12 | pub const Kevent = extern struct { |
| ... | ... | @@ -22,6 +25,65 @@ pub const dl_phdr_info = extern struct { |
| 22 | 25 | dlpi_phnum: u16, |
| 23 | 26 | }; |
| 24 | 27 | |
| 28 | pub const addrinfo = extern struct { | |
| 29 | flags: i32, | |
| 30 | family: i32, | |
| 31 | socktype: i32, | |
| 32 | protocol: i32, | |
| 33 | addrlen: socklen_t, | |
| 34 | canonname: ?[*:0]u8, | |
| 35 | addr: ?*sockaddr, | |
| 36 | next: ?*addrinfo, | |
| 37 | }; | |
| 38 | ||
| 39 | pub const EAI = extern enum(c_int) { | |
| 40 | /// address family for hostname not supported | |
| 41 | ADDRFAMILY = 1, | |
| 42 | ||
| 43 | /// name could not be resolved at this time | |
| 44 | AGAIN = 2, | |
| 45 | ||
| 46 | /// flags parameter had an invalid value | |
| 47 | BADFLAGS = 3, | |
| 48 | ||
| 49 | /// non-recoverable failure in name resolution | |
| 50 | FAIL = 4, | |
| 51 | ||
| 52 | /// address family not recognized | |
| 53 | FAMILY = 5, | |
| 54 | ||
| 55 | /// memory allocation failure | |
| 56 | MEMORY = 6, | |
| 57 | ||
| 58 | /// no address associated with hostname | |
| 59 | NODATA = 7, | |
| 60 | ||
| 61 | /// name does not resolve | |
| 62 | NONAME = 8, | |
| 63 | ||
| 64 | /// service not recognized for socket type | |
| 65 | SERVICE = 9, | |
| 66 | ||
| 67 | /// intended socket type was not recognized | |
| 68 | SOCKTYPE = 10, | |
| 69 | ||
| 70 | /// system error returned in errno | |
| 71 | SYSTEM = 11, | |
| 72 | ||
| 73 | /// invalid value for hints | |
| 74 | BADHINTS = 12, | |
| 75 | ||
| 76 | /// resolved protocol is unknown | |
| 77 | PROTOCOL = 13, | |
| 78 | ||
| 79 | /// argument buffer overflow | |
| 80 | OVERFLOW = 14, | |
| 81 | ||
| 82 | _, | |
| 83 | }; | |
| 84 | ||
| 85 | pub const EAI_MAX = 15; | |
| 86 | ||
| 25 | 87 | pub const msghdr = extern struct { |
| 26 | 88 | /// optional address |
| 27 | 89 | msg_name: ?*sockaddr, |
| ... | ... | @@ -68,9 +130,6 @@ pub const msghdr_const = extern struct { |
| 68 | 130 | msg_flags: i32, |
| 69 | 131 | }; |
| 70 | 132 | |
| 71 | pub const off_t = i64; | |
| 72 | pub const ino_t = u64; | |
| 73 | ||
| 74 | 133 | /// Renamed to Stat to not conflict with the stat function. |
| 75 | 134 | /// atime, mtime, and ctime have functions to return `timespec`, |
| 76 | 135 | /// because although this is a POSIX API, the layout and names of |
| ... | ... | @@ -122,7 +181,6 @@ pub const dirent = extern struct { |
| 122 | 181 | d_reclen: u16, |
| 123 | 182 | d_namlen: u16, |
| 124 | 183 | d_type: u8, |
| 125 | d_off: i64, | |
| 126 | 184 | d_name: [512]u8, |
| 127 | 185 | |
| 128 | 186 | pub fn reclen(self: dirent) u16 { |
| ... | ... | @@ -146,7 +204,7 @@ pub const sockaddr = extern struct { |
| 146 | 204 | |
| 147 | 205 | pub const sockaddr_in = extern struct { |
| 148 | 206 | len: u8 = @sizeOf(sockaddr_in), |
| 149 | family: sa_family_t, | |
| 207 | family: sa_family_t = AF_INET, | |
| 150 | 208 | port: in_port_t, |
| 151 | 209 | addr: u32, |
| 152 | 210 | zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }, |
| ... | ... | @@ -154,7 +212,7 @@ pub const sockaddr_in = extern struct { |
| 154 | 212 | |
| 155 | 213 | pub const sockaddr_in6 = extern struct { |
| 156 | 214 | len: u8 = @sizeOf(sockaddr_in6), |
| 157 | family: sa_family_t, | |
| 215 | family: sa_family_t = AF_INET6, | |
| 158 | 216 | port: in_port_t, |
| 159 | 217 | flowinfo: u32, |
| 160 | 218 | addr: [16]u8, |
| ... | ... | @@ -167,12 +225,27 @@ pub const sockaddr_un = extern struct { |
| 167 | 225 | len: u8 = @sizeOf(sockaddr_un), |
| 168 | 226 | |
| 169 | 227 | /// AF_LOCAL |
| 170 | family: sa_family_t, | |
| 228 | family: sa_family_t = AF_LOCAL, | |
| 171 | 229 | |
| 172 | 230 | /// path name |
| 173 | 231 | path: [104]u8, |
| 174 | 232 | }; |
| 175 | 233 | |
| 234 | /// get address to use bind() | |
| 235 | pub const AI_PASSIVE = 0x00000001; | |
| 236 | ||
| 237 | /// fill ai_canonname | |
| 238 | pub const AI_CANONNAME = 0x00000002; | |
| 239 | ||
| 240 | /// prevent host name resolution | |
| 241 | pub const AI_NUMERICHOST = 0x00000004; | |
| 242 | ||
| 243 | /// prevent service name resolution | |
| 244 | pub const AI_NUMERICSERV = 0x00000008; | |
| 245 | ||
| 246 | /// only if any address is assigned | |
| 247 | pub const AI_ADDRCONFIG = 0x00000400; | |
| 248 | ||
| 176 | 249 | pub const CTL_KERN = 1; |
| 177 | 250 | pub const CTL_DEBUG = 5; |
| 178 | 251 | |
| ... | ... | @@ -274,30 +347,71 @@ pub const X_OK = 1; // test for execute or search permission |
| 274 | 347 | pub const W_OK = 2; // test for write permission |
| 275 | 348 | pub const R_OK = 4; // test for read permission |
| 276 | 349 | |
| 277 | pub const O_RDONLY = 0x0000; | |
| 278 | pub const O_WRONLY = 0x0001; | |
| 279 | pub const O_RDWR = 0x0002; | |
| 280 | pub const O_ACCMODE = 0x0003; | |
| 281 | ||
| 282 | pub const O_CREAT = 0x0200; | |
| 283 | pub const O_EXCL = 0x0800; | |
| 284 | pub const O_NOCTTY = 0x8000; | |
| 285 | pub const O_TRUNC = 0x0400; | |
| 286 | pub const O_APPEND = 0x0008; | |
| 287 | pub const O_NONBLOCK = 0x0004; | |
| 350 | /// open for reading only | |
| 351 | pub const O_RDONLY = 0x00000000; | |
| 352 | ||
| 353 | /// open for writing only | |
| 354 | pub const O_WRONLY = 0x00000001; | |
| 355 | ||
| 356 | /// open for reading and writing | |
| 357 | pub const O_RDWR = 0x00000002; | |
| 358 | ||
| 359 | /// mask for above modes | |
| 360 | pub const O_ACCMODE = 0x00000003; | |
| 361 | ||
| 362 | /// no delay | |
| 363 | pub const O_NONBLOCK = 0x00000004; | |
| 364 | ||
| 365 | /// set append mode | |
| 366 | pub const O_APPEND = 0x00000008; | |
| 367 | ||
| 368 | /// open with shared file lock | |
| 369 | pub const O_SHLOCK = 0x00000010; | |
| 370 | ||
| 371 | /// open with exclusive file lock | |
| 372 | pub const O_EXLOCK = 0x00000020; | |
| 373 | ||
| 374 | /// signal pgrp when data ready | |
| 375 | pub const O_ASYNC = 0x00000040; | |
| 376 | ||
| 377 | /// synchronous writes | |
| 378 | pub const O_SYNC = 0x00000080; | |
| 379 | ||
| 380 | /// don't follow symlinks on the last | |
| 381 | pub const O_NOFOLLOW = 0x00000100; | |
| 382 | ||
| 383 | /// create if nonexistent | |
| 384 | pub const O_CREAT = 0x00000200; | |
| 385 | ||
| 386 | /// truncate to zero length | |
| 387 | pub const O_TRUNC = 0x00000400; | |
| 388 | ||
| 389 | /// error if already exists | |
| 390 | pub const O_EXCL = 0x00000800; | |
| 391 | ||
| 392 | /// don't assign controlling terminal | |
| 393 | pub const O_NOCTTY = 0x00008000; | |
| 394 | ||
| 395 | /// write: I/O data completion | |
| 288 | 396 | pub const O_DSYNC = 0x00010000; |
| 289 | pub const O_SYNC = 0x0080; | |
| 397 | ||
| 398 | /// read: I/O completion as for write | |
| 290 | 399 | pub const O_RSYNC = 0x00020000; |
| 291 | pub const O_DIRECTORY = 0x00080000; | |
| 292 | pub const O_NOFOLLOW = 0x00000100; | |
| 293 | pub const O_CLOEXEC = 0x00400000; | |
| 294 | 400 | |
| 295 | pub const O_ASYNC = 0x0040; | |
| 401 | /// use alternate i/o semantics | |
| 402 | pub const O_ALT_IO = 0x00040000; | |
| 403 | ||
| 404 | /// direct I/O hint | |
| 296 | 405 | pub const O_DIRECT = 0x00080000; |
| 297 | pub const O_NOATIME = 0; | |
| 298 | pub const O_PATH = 0; | |
| 299 | pub const O_TMPFILE = 0; | |
| 300 | pub const O_NDELAY = O_NONBLOCK; | |
| 406 | ||
| 407 | /// fail if not a directory | |
| 408 | pub const O_DIRECTORY = 0x00200000; | |
| 409 | ||
| 410 | /// set close on exec | |
| 411 | pub const O_CLOEXEC = 0x00400000; | |
| 412 | ||
| 413 | /// skip search permission checks | |
| 414 | pub const O_SEARCH = 0x00800000; | |
| 301 | 415 | |
| 302 | 416 | pub const F_DUPFD = 0; |
| 303 | 417 | pub const F_GETFD = 1; |
| ... | ... | @@ -816,6 +930,23 @@ pub fn S_IWHT(m: u32) bool { |
| 816 | 930 | return m & S_IFMT == S_IFWHT; |
| 817 | 931 | } |
| 818 | 932 | |
| 933 | /// Magic value that specify the use of the current working directory | |
| 934 | /// to determine the target of relative file paths in the openat() and | |
| 935 | /// similar syscalls. | |
| 936 | pub const AT_FDCWD = -100; | |
| 937 | ||
| 938 | /// Check access using effective user and group ID | |
| 939 | pub const AT_EACCESS = 0x0100; | |
| 940 | ||
| 941 | /// Do not follow symbolic links | |
| 942 | pub const AT_SYMLINK_NOFOLLOW = 0x0200; | |
| 943 | ||
| 944 | /// Follow symbolic link | |
| 945 | pub const AT_SYMLINK_FOLLOW = 0x0400; | |
| 946 | ||
| 947 | /// Remove directory instead of file | |
| 948 | pub const AT_REMOVEDIR = 0x0800; | |
| 949 | ||
| 819 | 950 | pub const HOST_NAME_MAX = 255; |
| 820 | 951 | |
| 821 | 952 | /// dummy for IP |
lib/std/thread.zig+73-26| ... | ... | @@ -292,32 +292,69 @@ pub const Thread = struct { |
| 292 | 292 | l += tls_img.alloc_size; |
| 293 | 293 | } |
| 294 | 294 | } |
| 295 | break :blk l; | |
| 295 | // Round the size to the page size. | |
| 296 | break :blk mem.alignForward(l, mem.page_size); | |
| 296 | 297 | }; |
| 297 | // Map the whole stack with no rw permissions to avoid committing the | |
| 298 | // whole region right away | |
| 299 | const mmap_slice = os.mmap( | |
| 300 | null, | |
| 301 | mem.alignForward(mmap_len, mem.page_size), | |
| 302 | os.PROT_NONE, | |
| 303 | os.MAP_PRIVATE | os.MAP_ANONYMOUS, | |
| 304 | -1, | |
| 305 | 0, | |
| 306 | ) catch |err| switch (err) { | |
| 307 | error.MemoryMappingNotSupported => unreachable, | |
| 308 | error.AccessDenied => unreachable, | |
| 309 | error.PermissionDenied => unreachable, | |
| 310 | else => |e| return e, | |
| 311 | }; | |
| 312 | errdefer os.munmap(mmap_slice); | |
| 313 | ||
| 314 | // Map everything but the guard page as rw | |
| 315 | os.mprotect( | |
| 316 | mmap_slice, | |
| 317 | os.PROT_READ | os.PROT_WRITE, | |
| 318 | ) catch |err| switch (err) { | |
| 319 | error.AccessDenied => unreachable, | |
| 320 | else => |e| return e, | |
| 298 | ||
| 299 | const mmap_slice = mem: { | |
| 300 | if (std.Target.current.os.tag != .netbsd) { | |
| 301 | // Map the whole stack with no rw permissions to avoid | |
| 302 | // committing the whole region right away | |
| 303 | const mmap_slice = os.mmap( | |
| 304 | null, | |
| 305 | mmap_len, | |
| 306 | os.PROT_NONE, | |
| 307 | os.MAP_PRIVATE | os.MAP_ANONYMOUS, | |
| 308 | -1, | |
| 309 | 0, | |
| 310 | ) catch |err| switch (err) { | |
| 311 | error.MemoryMappingNotSupported => unreachable, | |
| 312 | error.AccessDenied => unreachable, | |
| 313 | error.PermissionDenied => unreachable, | |
| 314 | else => |e| return e, | |
| 315 | }; | |
| 316 | errdefer os.munmap(mmap_slice); | |
| 317 | ||
| 318 | // Map everything but the guard page as rw | |
| 319 | os.mprotect( | |
| 320 | mmap_slice[guard_end_offset..], | |
| 321 | os.PROT_READ | os.PROT_WRITE, | |
| 322 | ) catch |err| switch (err) { | |
| 323 | error.AccessDenied => unreachable, | |
| 324 | else => |e| return e, | |
| 325 | }; | |
| 326 | ||
| 327 | break :mem mmap_slice; | |
| 328 | } else { | |
| 329 | // NetBSD mprotect is very strict and doesn't allow to "upgrade" | |
| 330 | // a PROT_NONE mapping to a RW one so let's allocate everything | |
| 331 | // right away | |
| 332 | const mmap_slice = os.mmap( | |
| 333 | null, | |
| 334 | mmap_len, | |
| 335 | os.PROT_READ | os.PROT_WRITE, | |
| 336 | os.MAP_PRIVATE | os.MAP_ANONYMOUS, | |
| 337 | -1, | |
| 338 | 0, | |
| 339 | ) catch |err| switch (err) { | |
| 340 | error.MemoryMappingNotSupported => unreachable, | |
| 341 | error.AccessDenied => unreachable, | |
| 342 | error.PermissionDenied => unreachable, | |
| 343 | else => |e| return e, | |
| 344 | }; | |
| 345 | errdefer os.munmap(mmap_slice); | |
| 346 | ||
| 347 | // Remap the guard page with no permissions | |
| 348 | os.mprotect( | |
| 349 | mmap_slice[0..guard_end_offset], | |
| 350 | os.PROT_NONE, | |
| 351 | ) catch |err| switch (err) { | |
| 352 | error.AccessDenied => unreachable, | |
| 353 | else => |e| return e, | |
| 354 | }; | |
| 355 | ||
| 356 | break :mem mmap_slice; | |
| 357 | } | |
| 321 | 358 | }; |
| 322 | 359 | |
| 323 | 360 | const mmap_addr = @ptrToInt(mmap_slice.ptr); |
| ... | ... | @@ -338,7 +375,17 @@ pub const Thread = struct { |
| 338 | 375 | if (c.pthread_attr_init(&attr) != 0) return error.SystemResources; |
| 339 | 376 | defer assert(c.pthread_attr_destroy(&attr) == 0); |
| 340 | 377 | |
| 341 | assert(c.pthread_attr_setstack(&attr, mmap_slice.ptr, stack_end_offset) == 0); | |
| 378 | // Tell pthread where the effective stack start is and its size | |
| 379 | assert(c.pthread_attr_setstack( | |
| 380 | &attr, | |
| 381 | mmap_slice.ptr + guard_end_offset, | |
| 382 | stack_end_offset - guard_end_offset, | |
| 383 | ) == 0); | |
| 384 | // Even though pthread's man pages state that the guard size is | |
| 385 | // ignored when the stack address is explicitly given, on some | |
| 386 | // plaforms such as NetBSD we still have to zero it to prevent | |
| 387 | // random crashes in pthread_join calls | |
| 388 | assert(c.pthread_attr_setguardsize(&attr, 0) == 0); | |
| 342 | 389 | |
| 343 | 390 | const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg)); |
| 344 | 391 | switch (err) { |
src/link.cpp+3-1| ... | ... | @@ -1799,7 +1799,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1799 | 1799 | lj->args.append("-lm"); |
| 1800 | 1800 | } |
| 1801 | 1801 | |
| 1802 | if (g->zig_target->os == OsFreeBSD) { | |
| 1802 | if (g->zig_target->os == OsFreeBSD || | |
| 1803 | g->zig_target->os == OsNetBSD) | |
| 1804 | { | |
| 1803 | 1805 | lj->args.append("-lpthread"); |
| 1804 | 1806 | } |
| 1805 | 1807 | } else if (target_is_glibc(g->zig_target)) { |
src/os.cpp-3| ... | ... | @@ -1161,9 +1161,6 @@ Error os_update_file(Buf *src_path, Buf *dst_path) { |
| 1161 | 1161 | fclose(dst_libc_file); |
| 1162 | 1162 | return err; |
| 1163 | 1163 | } |
| 1164 | if (fflush(src_libc_file) == -1) { | |
| 1165 | return ErrorUnexpected; | |
| 1166 | } | |
| 1167 | 1164 | if (fflush(dst_libc_file) == -1) { |
| 1168 | 1165 | return ErrorUnexpected; |
| 1169 | 1166 | } |