authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 17:53:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 17:53:47-07:00
log71ac5b151524288562bb78d9b0924bb3b0ba5e1c
tree4c204780f7877567e64f6d30f40204063ed06eed
parent9052e0b1377e4c4cd23b979b4a486df27a3444bd
parent05b1a7414e2737fd987071a03a3fc8387b4fd268

Merge branch 'semarie-openbsd-minimal'


22 files changed, 1181 insertions(+), 41 deletions(-)

lib/std/c.zig+1-1
...@@ -249,7 +249,7 @@ pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;...@@ -249,7 +249,7 @@ pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
249pub extern "c" fn malloc(usize) ?*c_void;249pub extern "c" fn malloc(usize) ?*c_void;
250250
251pub usingnamespace switch (builtin.os.tag) {251pub usingnamespace switch (builtin.os.tag) {
252 .linux, .freebsd, .kfreebsd, .netbsd, .openbsd => struct {252 .linux, .freebsd, .kfreebsd, .netbsd => struct {
253 pub extern "c" fn malloc_usable_size(?*const c_void) usize;253 pub extern "c" fn malloc_usable_size(?*const c_void) usize;
254 },254 },
255 .macos, .ios, .watchos, .tvos => struct {255 .macos, .ios, .watchos, .tvos => struct {
lib/std/c/openbsd.zig+23
...@@ -3,9 +3,32 @@...@@ -3,9 +3,32 @@
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.5// and substantial portions of the software.
6const std = @import("../std.zig");
7const builtin = std.builtin;
8
9usingnamespace std.c;
10
11extern "c" fn __errno() *c_int;
12pub const _errno = __errno;
13
14pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
15pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
16
17pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
18
19pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
20pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
21
6pub const pthread_mutex_t = extern struct {22pub const pthread_mutex_t = extern struct {
7 inner: ?*c_void = null,23 inner: ?*c_void = null,
8};24};
9pub const pthread_cond_t = extern struct {25pub const pthread_cond_t = extern struct {
10 inner: ?*c_void = null,26 inner: ?*c_void = null,
11};27};
28pub const pthread_spinlock_t = extern struct {
29 inner: ?*c_void = null,
30};
31
32pub const pthread_attr_t = extern struct {
33 inner: ?*c_void = null,
34};
lib/std/debug.zig+2-1
...@@ -654,6 +654,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {...@@ -654,6 +654,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
654 .freebsd,654 .freebsd,
655 .netbsd,655 .netbsd,
656 .dragonfly,656 .dragonfly,
657 .openbsd,
657 .macos,658 .macos,
658 .windows,659 .windows,
659 => return DebugInfo.init(allocator),660 => return DebugInfo.init(allocator),
...@@ -1640,7 +1641,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {...@@ -1640,7 +1641,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
1640 };1641 };
1641 }1642 }
1642 },1643 },
1643 .linux, .netbsd, .freebsd, .dragonfly => struct {1644 .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct {
1644 base_address: usize,1645 base_address: usize,
1645 dwarf: DW.DwarfInfo,1646 dwarf: DW.DwarfInfo,
1646 mapped_memory: []const u8,1647 mapped_memory: []const u8,
lib/std/dynamic_library.zig+2-2
...@@ -19,7 +19,7 @@ const max = std.math.max;...@@ -19,7 +19,7 @@ const max = std.math.max;
19pub const DynLib = switch (builtin.os.tag) {19pub const DynLib = switch (builtin.os.tag) {
20 .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,20 .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
21 .windows => WindowsDynLib,21 .windows => WindowsDynLib,
22 .macos, .tvos, .watchos, .ios, .freebsd => DlDynlib,22 .macos, .tvos, .watchos, .ios, .freebsd, .openbsd => DlDynlib,
23 else => void,23 else => void,
24};24};
2525
...@@ -402,7 +402,7 @@ pub const DlDynlib = struct {...@@ -402,7 +402,7 @@ pub const DlDynlib = struct {
402402
403test "dynamic_library" {403test "dynamic_library" {
404 const libname = switch (builtin.os.tag) {404 const libname = switch (builtin.os.tag) {
405 .linux, .freebsd => "invalid_so.so",405 .linux, .freebsd, .openbsd => "invalid_so.so",
406 .windows => "invalid_dll.dll",406 .windows => "invalid_dll.dll",
407 .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",407 .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",
408 else => return error.SkipZigTest,408 else => return error.SkipZigTest,
lib/std/event/loop.zig+12-11
...@@ -69,7 +69,7 @@ pub const Loop = struct {...@@ -69,7 +69,7 @@ pub const Loop = struct {
69 };69 };
7070
71 pub const EventFd = switch (builtin.os.tag) {71 pub const EventFd = switch (builtin.os.tag) {
72 .macos, .freebsd, .netbsd, .dragonfly => KEventFd,72 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventFd,
73 .linux => struct {73 .linux => struct {
74 base: ResumeNode,74 base: ResumeNode,
75 epoll_op: u32,75 epoll_op: u32,
...@@ -88,7 +88,7 @@ pub const Loop = struct {...@@ -88,7 +88,7 @@ pub const Loop = struct {
88 };88 };
8989
90 pub const Basic = switch (builtin.os.tag) {90 pub const Basic = switch (builtin.os.tag) {
91 .macos, .freebsd, .netbsd, .dragonfly => KEventBasic,91 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventBasic,
92 .linux => struct {92 .linux => struct {
93 base: ResumeNode,93 base: ResumeNode,
94 },94 },
...@@ -266,7 +266,7 @@ pub const Loop = struct {...@@ -266,7 +266,7 @@ pub const Loop = struct {
266 self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);266 self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);
267 }267 }
268 },268 },
269 .macos, .freebsd, .netbsd, .dragonfly => {269 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
270 self.os_data.kqfd = try os.kqueue();270 self.os_data.kqfd = try os.kqueue();
271 errdefer os.close(self.os_data.kqfd);271 errdefer os.close(self.os_data.kqfd);
272272
...@@ -391,7 +391,7 @@ pub const Loop = struct {...@@ -391,7 +391,7 @@ pub const Loop = struct {
391 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);391 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
392 os.close(self.os_data.epollfd);392 os.close(self.os_data.epollfd);
393 },393 },
394 .macos, .freebsd, .netbsd, .dragonfly => {394 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
395 os.close(self.os_data.kqfd);395 os.close(self.os_data.kqfd);
396 },396 },
397 .windows => {397 .windows => {
...@@ -485,7 +485,7 @@ pub const Loop = struct {...@@ -485,7 +485,7 @@ pub const Loop = struct {
485 .linux => {485 .linux => {
486 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN);486 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN);
487 },487 },
488 .macos, .freebsd, .netbsd, .dragonfly => {488 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
489 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);489 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
490 },490 },
491 else => @compileError("Unsupported OS"),491 else => @compileError("Unsupported OS"),
...@@ -497,7 +497,7 @@ pub const Loop = struct {...@@ -497,7 +497,7 @@ pub const Loop = struct {
497 .linux => {497 .linux => {
498 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT);498 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT);
499 },499 },
500 .macos, .freebsd, .netbsd, .dragonfly => {500 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
501 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);501 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
502 },502 },
503 else => @compileError("Unsupported OS"),503 else => @compileError("Unsupported OS"),
...@@ -509,7 +509,7 @@ pub const Loop = struct {...@@ -509,7 +509,7 @@ pub const Loop = struct {
509 .linux => {509 .linux => {
510 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);510 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
511 },511 },
512 .macos, .freebsd, .netbsd, .dragonfly => {512 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
513 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);513 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
514 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);514 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
515 },515 },
...@@ -578,7 +578,7 @@ pub const Loop = struct {...@@ -578,7 +578,7 @@ pub const Loop = struct {
578 const eventfd_node = &resume_stack_node.data;578 const eventfd_node = &resume_stack_node.data;
579 eventfd_node.base.handle = next_tick_node.data;579 eventfd_node.base.handle = next_tick_node.data;
580 switch (builtin.os.tag) {580 switch (builtin.os.tag) {
581 .macos, .freebsd, .netbsd, .dragonfly => {581 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
582 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);582 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
583 const empty_kevs = &[0]os.Kevent{};583 const empty_kevs = &[0]os.Kevent{};
584 _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {584 _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
...@@ -644,6 +644,7 @@ pub const Loop = struct {...@@ -644,6 +644,7 @@ pub const Loop = struct {
644 .freebsd,644 .freebsd,
645 .netbsd,645 .netbsd,
646 .dragonfly,646 .dragonfly,
647 .openbsd,
647 => self.fs_thread.wait(),648 => self.fs_thread.wait(),
648 else => {},649 else => {},
649 }650 }
...@@ -736,7 +737,7 @@ pub const Loop = struct {...@@ -736,7 +737,7 @@ pub const Loop = struct {
736 }737 }
737 return;738 return;
738 },739 },
739 .macos, .freebsd, .netbsd, .dragonfly => {740 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
740 const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);741 const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
741 const empty_kevs = &[0]os.Kevent{};742 const empty_kevs = &[0]os.Kevent{};
742 // cannot fail because we already added it and this just enables it743 // cannot fail because we already added it and this just enables it
...@@ -1351,7 +1352,7 @@ pub const Loop = struct {...@@ -1351,7 +1352,7 @@ pub const Loop = struct {
1351 }1352 }
1352 }1353 }
1353 },1354 },
1354 .macos, .freebsd, .netbsd, .dragonfly => {1355 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
1355 var eventlist: [1]os.Kevent = undefined;1356 var eventlist: [1]os.Kevent = undefined;
1356 const empty_kevs = &[0]os.Kevent{};1357 const empty_kevs = &[0]os.Kevent{};
1357 const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;1358 const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
...@@ -1477,7 +1478,7 @@ pub const Loop = struct {...@@ -1477,7 +1478,7 @@ pub const Loop = struct {
14771478
1478 const OsData = switch (builtin.os.tag) {1479 const OsData = switch (builtin.os.tag) {
1479 .linux => LinuxOsData,1480 .linux => LinuxOsData,
1480 .macos, .freebsd, .netbsd, .dragonfly => KEventData,1481 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventData,
1481 .windows => struct {1482 .windows => struct {
1482 io_port: windows.HANDLE,1483 io_port: windows.HANDLE,
1483 extra_thread_count: usize,1484 extra_thread_count: usize,
lib/std/fs.zig+42-5
...@@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;...@@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
39/// fit into a UTF-8 encoded array of this length.39/// fit into a UTF-8 encoded array of this length.
40/// The byte count includes room for a null sentinel byte.40/// The byte count includes room for a null sentinel byte.
41pub const MAX_PATH_BYTES = switch (builtin.os.tag) {41pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
42 .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX,42 .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => os.PATH_MAX,
43 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.43 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
44 // If it would require 4 UTF-8 bytes, then there would be a surrogate44 // If it would require 4 UTF-8 bytes, then there would be a surrogate
45 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.45 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
...@@ -303,7 +303,7 @@ pub const Dir = struct {...@@ -303,7 +303,7 @@ pub const Dir = struct {
303 const IteratorError = error{AccessDenied} || os.UnexpectedError;303 const IteratorError = error{AccessDenied} || os.UnexpectedError;
304304
305 pub const Iterator = switch (builtin.os.tag) {305 pub const Iterator = switch (builtin.os.tag) {
306 .macos, .ios, .freebsd, .netbsd, .dragonfly => struct {306 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
307 dir: Dir,307 dir: Dir,
308 seek: i64,308 seek: i64,
309 buf: [8192]u8, // TODO align(@alignOf(os.dirent)),309 buf: [8192]u8, // TODO align(@alignOf(os.dirent)),
...@@ -319,7 +319,7 @@ pub const Dir = struct {...@@ -319,7 +319,7 @@ pub const Dir = struct {
319 pub fn next(self: *Self) Error!?Entry {319 pub fn next(self: *Self) Error!?Entry {
320 switch (builtin.os.tag) {320 switch (builtin.os.tag) {
321 .macos, .ios => return self.nextDarwin(),321 .macos, .ios => return self.nextDarwin(),
322 .freebsd, .netbsd, .dragonfly => return self.nextBsd(),322 .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
323 else => @compileError("unimplemented"),323 else => @compileError("unimplemented"),
324 }324 }
325 }325 }
...@@ -615,7 +615,7 @@ pub const Dir = struct {...@@ -615,7 +615,7 @@ pub const Dir = struct {
615615
616 pub fn iterate(self: Dir) Iterator {616 pub fn iterate(self: Dir) Iterator {
617 switch (builtin.os.tag) {617 switch (builtin.os.tag) {
618 .macos, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{618 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => return Iterator{
619 .dir = self,619 .dir = self,
620 .seek = 0,620 .seek = 0,
621 .index = 0,621 .index = 0,
...@@ -1302,7 +1302,7 @@ pub const Dir = struct {...@@ -1302,7 +1302,7 @@ pub const Dir = struct {
1302 error.AccessDenied => |e| switch (builtin.os.tag) {1302 error.AccessDenied => |e| switch (builtin.os.tag) {
1303 // non-Linux POSIX systems return EPERM when trying to delete a directory, so1303 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
1304 // we need to handle that case specifically and translate the error1304 // we need to handle that case specifically and translate the error
1305 .macos, .ios, .freebsd, .netbsd, .dragonfly => {1305 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
1306 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)1306 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
1307 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e;1307 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e;
1308 const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;1308 const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;
...@@ -2232,6 +2232,43 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {...@@ -2232,6 +2232,43 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
2232 // TODO could this slice from 0 to out_len instead?2232 // TODO could this slice from 0 to out_len instead?
2233 return mem.spanZ(@ptrCast([*:0]u8, out_buffer));2233 return mem.spanZ(@ptrCast([*:0]u8, out_buffer));
2234 },2234 },
2235 .openbsd => {
2236 // OpenBSD doesn't support getting the path of a running process, so try to guess it
2237 if (os.argv.len == 0)
2238 return error.FileNotFound;
2239
2240 const argv0 = mem.span(os.argv[0]);
2241 if (mem.indexOf(u8, argv0, "/") != null) {
2242 // argv[0] is a path (relative or absolute): use realpath(3) directly
2243 var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
2244 const real_path = try os.realpathZ(os.argv[0], &real_path_buf);
2245 if (real_path.len > out_buffer.len)
2246 return error.NameTooLong;
2247 mem.copy(u8, out_buffer, real_path);
2248 return out_buffer[0..real_path.len];
2249 } else if (argv0.len != 0) {
2250 // argv[0] is not empty (and not a path): search it inside PATH
2251 const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound;
2252 var path_it = mem.tokenize(PATH, &[_]u8{path.delimiter});
2253 while (path_it.next()) |a_path| {
2254 var resolved_path_buf: [MAX_PATH_BYTES]u8 = undefined;
2255 const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{
2256 a_path,
2257 os.argv[0],
2258 }) catch continue;
2259
2260 var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
2261 if (os.realpathZ(&resolved_path_buf, &real_path_buf)) |real_path| {
2262 // found a file, and hope it is the right file
2263 if (real_path.len > out_buffer.len)
2264 return error.NameTooLong;
2265 mem.copy(u8, out_buffer, real_path);
2266 return out_buffer[0..real_path.len];
2267 } else |_| continue;
2268 }
2269 }
2270 return error.FileNotFound;
2271 },
2235 .windows => {2272 .windows => {
2236 const utf16le_slice = selfExePathW();2273 const utf16le_slice = selfExePathW();
2237 // Trust that Windows gives us valid UTF-16LE.2274 // Trust that Windows gives us valid UTF-16LE.
lib/std/fs/get_app_data_dir.zig+1-1
...@@ -49,7 +49,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD...@@ -49,7 +49,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
49 };49 };
50 return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });50 return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
51 },51 },
52 .linux, .freebsd, .netbsd, .dragonfly => {52 .linux, .freebsd, .netbsd, .dragonfly, .openbsd => {
53 const home_dir = os.getenv("HOME") orelse {53 const home_dir = os.getenv("HOME") orelse {
54 // TODO look in /etc/passwd54 // TODO look in /etc/passwd
55 return error.AppDataDirUnavailable;55 return error.AppDataDirUnavailable;
lib/std/fs/watch.zig+4-4
...@@ -49,7 +49,7 @@ pub fn Watch(comptime V: type) type {...@@ -49,7 +49,7 @@ pub fn Watch(comptime V: type) type {
4949
50 const OsData = switch (builtin.os.tag) {50 const OsData = switch (builtin.os.tag) {
51 // TODO https://github.com/ziglang/zig/issues/377851 // TODO https://github.com/ziglang/zig/issues/3778
52 .macos, .freebsd, .netbsd, .dragonfly => KqOsData,52 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KqOsData,
53 .linux => LinuxOsData,53 .linux => LinuxOsData,
54 .windows => WindowsOsData,54 .windows => WindowsOsData,
5555
...@@ -160,7 +160,7 @@ pub fn Watch(comptime V: type) type {...@@ -160,7 +160,7 @@ pub fn Watch(comptime V: type) type {
160 return self;160 return self;
161 },161 },
162162
163 .macos, .freebsd, .netbsd, .dragonfly => {163 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
164 self.* = Self{164 self.* = Self{
165 .allocator = allocator,165 .allocator = allocator,
166 .channel = channel,166 .channel = channel,
...@@ -178,7 +178,7 @@ pub fn Watch(comptime V: type) type {...@@ -178,7 +178,7 @@ pub fn Watch(comptime V: type) type {
178 /// All addFile calls and removeFile calls must have completed.178 /// All addFile calls and removeFile calls must have completed.
179 pub fn deinit(self: *Self) void {179 pub fn deinit(self: *Self) void {
180 switch (builtin.os.tag) {180 switch (builtin.os.tag) {
181 .macos, .freebsd, .netbsd, .dragonfly => {181 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
182 // TODO we need to cancel the frames before destroying the lock182 // TODO we need to cancel the frames before destroying the lock
183 self.os_data.table_lock.deinit();183 self.os_data.table_lock.deinit();
184 var it = self.os_data.file_table.iterator();184 var it = self.os_data.file_table.iterator();
...@@ -229,7 +229,7 @@ pub fn Watch(comptime V: type) type {...@@ -229,7 +229,7 @@ pub fn Watch(comptime V: type) type {
229229
230 pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V {230 pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
231 switch (builtin.os.tag) {231 switch (builtin.os.tag) {
232 .macos, .freebsd, .netbsd, .dragonfly => return addFileKEvent(self, file_path, value),232 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => return addFileKEvent(self, file_path, value),
233 .linux => return addFileLinux(self, file_path, value),233 .linux => return addFileLinux(self, file_path, value),
234 .windows => return addFileWindows(self, file_path, value),234 .windows => return addFileWindows(self, file_path, value),
235 else => @compileError("Unsupported OS"),235 else => @compileError("Unsupported OS"),
lib/std/os.zig+5-2
...@@ -33,6 +33,7 @@ pub const darwin = @import("os/darwin.zig");...@@ -33,6 +33,7 @@ pub const darwin = @import("os/darwin.zig");
33pub const dragonfly = @import("os/dragonfly.zig");33pub const dragonfly = @import("os/dragonfly.zig");
34pub const freebsd = @import("os/freebsd.zig");34pub const freebsd = @import("os/freebsd.zig");
35pub const netbsd = @import("os/netbsd.zig");35pub const netbsd = @import("os/netbsd.zig");
36pub const openbsd = @import("os/openbsd.zig");
36pub const linux = @import("os/linux.zig");37pub const linux = @import("os/linux.zig");
37pub const uefi = @import("os/uefi.zig");38pub const uefi = @import("os/uefi.zig");
38pub const wasi = @import("os/wasi.zig");39pub const wasi = @import("os/wasi.zig");
...@@ -47,6 +48,7 @@ test "" {...@@ -47,6 +48,7 @@ test "" {
47 _ = freebsd;48 _ = freebsd;
48 _ = linux;49 _ = linux;
49 _ = netbsd;50 _ = netbsd;
51 _ = openbsd;
50 _ = uefi;52 _ = uefi;
51 _ = wasi;53 _ = wasi;
52 _ = windows;54 _ = windows;
...@@ -66,6 +68,7 @@ else switch (builtin.os.tag) {...@@ -66,6 +68,7 @@ else switch (builtin.os.tag) {
66 .freebsd => freebsd,68 .freebsd => freebsd,
67 .linux => linux,69 .linux => linux,
68 .netbsd => netbsd,70 .netbsd => netbsd,
71 .openbsd => openbsd,
69 .dragonfly => dragonfly,72 .dragonfly => dragonfly,
70 .wasi => wasi,73 .wasi => wasi,
71 .windows => windows,74 .windows => windows,
...@@ -161,8 +164,8 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -161,8 +164,8 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
161 }164 }
162 return;165 return;
163 }166 }
164 if (builtin.os.tag == .netbsd) {167 if (builtin.os.tag == .netbsd or builtin.os.tag == .openbsd) {
165 netbsd.arc4random_buf(buffer.ptr, buffer.len);168 system.arc4random_buf(buffer.ptr, buffer.len);
166 return;169 return;
167 }170 }
168 if (builtin.os.tag == .wasi) {171 if (builtin.os.tag == .wasi) {
lib/std/os/bits.zig+1
...@@ -17,6 +17,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {...@@ -17,6 +17,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {
17 .freebsd => @import("bits/freebsd.zig"),17 .freebsd => @import("bits/freebsd.zig"),
18 .linux => @import("bits/linux.zig"),18 .linux => @import("bits/linux.zig"),
19 .netbsd => @import("bits/netbsd.zig"),19 .netbsd => @import("bits/netbsd.zig"),
20 .openbsd => @import("bits/openbsd.zig"),
20 .wasi => @import("bits/wasi.zig"),21 .wasi => @import("bits/wasi.zig"),
21 .windows => @import("bits/windows.zig"),22 .windows => @import("bits/windows.zig"),
22 else => struct {},23 else => struct {},
lib/std/os/bits/openbsd.zig created+1052
...@@ -0,0 +1,1052 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2020 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("../../std.zig");
7const builtin = std.builtin;
8const maxInt = std.math.maxInt;
9
10pub const blkcnt_t = i64;
11pub const blksize_t = i32;
12pub const clock_t = i64;
13pub const dev_t = i32;
14pub const fd_t = c_int;
15pub const gid_t = u32;
16pub const ino_t = u64;
17pub const mode_t = u32;
18pub const nlink_t = u32;
19pub const off_t = i64;
20pub const pid_t = i32;
21pub const socklen_t = u32;
22pub const time_t = i64;
23pub const uid_t = u32;
24
25/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
26pub const Kevent = extern struct {
27 ident: usize,
28 filter: c_short,
29 flags: u16,
30 fflags: c_uint,
31 data: i64,
32 udata: usize,
33};
34
35pub const dl_phdr_info = extern struct {
36 dlpi_addr: usize,
37 dlpi_name: ?[*:0]const u8,
38 dlpi_phdr: [*]std.elf.Phdr,
39 dlpi_phnum: u16,
40};
41
42pub const Flock = extern struct {
43 l_start: off_t,
44 l_len: off_t,
45 l_pid: pid_t,
46 l_type: i16,
47 l_whence: i16,
48};
49
50pub const addrinfo = extern struct {
51 flags: i32,
52 family: i32,
53 socktype: i32,
54 protocol: i32,
55 addrlen: socklen_t,
56 canonname: ?[*:0]u8,
57 addr: ?*sockaddr,
58 next: ?*addrinfo,
59};
60
61pub const EAI = extern enum(c_int) {
62 /// address family for hostname not supported
63 ADDRFAMILY = -9,
64
65 /// name could not be resolved at this time
66 AGAIN = -3,
67
68 /// flags parameter had an invalid value
69 BADFLAGS = -1,
70
71 /// non-recoverable failure in name resolution
72 FAIL = -4,
73
74 /// address family not recognized
75 FAMILY = -6,
76
77 /// memory allocation failure
78 MEMORY = -10,
79
80 /// no address associated with hostname
81 NODATA = -5,
82
83 /// name does not resolve
84 NONAME = -2,
85
86 /// service not recognized for socket type
87 SERVICE = -8,
88
89 /// intended socket type was not recognized
90 SOCKTYPE = -7,
91
92 /// system error returned in errno
93 SYSTEM = -11,
94
95 /// invalid value for hints
96 BADHINTS = -12,
97
98 /// resolved protocol is unknown
99 PROTOCOL = -13,
100
101 /// argument buffer overflow
102 OVERFLOW = -14,
103
104 _,
105};
106
107pub const EAI_MAX = 15;
108
109pub const msghdr = extern struct {
110 /// optional address
111 msg_name: ?*sockaddr,
112
113 /// size of address
114 msg_namelen: socklen_t,
115
116 /// scatter/gather array
117 msg_iov: [*]iovec,
118
119 /// # elements in msg_iov
120 msg_iovlen: i32,
121
122 /// ancillary data
123 msg_control: ?*c_void,
124
125 /// ancillary data buffer len
126 msg_controllen: socklen_t,
127
128 /// flags on received message
129 msg_flags: i32,
130};
131
132pub const msghdr_const = extern struct {
133 /// optional address
134 msg_name: ?*const sockaddr,
135
136 /// size of address
137 msg_namelen: socklen_t,
138
139 /// scatter/gather array
140 msg_iov: [*]iovec_const,
141
142 /// # elements in msg_iov
143 msg_iovlen: i32,
144
145 /// ancillary data
146 msg_control: ?*c_void,
147
148 /// ancillary data buffer len
149 msg_controllen: socklen_t,
150
151 /// flags on received message
152 msg_flags: i32,
153};
154
155/// Renamed to Stat to not conflict with the stat function.
156/// atime, mtime, and ctime have functions to return `timespec`,
157/// because although this is a POSIX API, the layout and names of
158/// the structs are inconsistent across operating systems, and
159/// in C, macros are used to hide the differences. Here we use
160/// methods to accomplish this.
161pub const Stat = extern struct {
162 mode: mode_t,
163 dev: dev_t,
164 ino: ino_t,
165 nlink: nlink_t,
166 uid: uid_t,
167 gid: gid_t,
168 rdev: dev_t,
169 atim: timespec,
170 mtim: timespec,
171 ctim: timespec,
172 size: off_t,
173 blocks: blkcnt_t,
174 blksize: blksize_t,
175 flags: u32,
176 gen: u32,
177 birthtim: timespec,
178
179 pub fn atime(self: Stat) timespec {
180 return self.atim;
181 }
182
183 pub fn mtime(self: Stat) timespec {
184 return self.mtim;
185 }
186
187 pub fn ctime(self: Stat) timespec {
188 return self.ctim;
189 }
190};
191
192pub const timespec = extern struct {
193 tv_sec: time_t,
194 tv_nsec: isize,
195};
196
197pub const MAXNAMLEN = 255;
198
199pub const dirent = extern struct {
200 d_fileno: ino_t,
201 d_off: off_t,
202 d_reclen: u16,
203 d_type: u8,
204 d_namlen: u8,
205 __d_padding: [4]u8,
206 d_name: [MAXNAMLEN + 1]u8,
207
208 pub fn reclen(self: dirent) u16 {
209 return self.d_reclen;
210 }
211};
212
213pub const in_port_t = u16;
214pub const sa_family_t = u8;
215
216pub const sockaddr = extern struct {
217 /// total length
218 len: u8,
219
220 /// address family
221 family: sa_family_t,
222
223 /// actually longer; address value
224 data: [14]u8,
225};
226
227pub const sockaddr_in = extern struct {
228 len: u8 = @sizeOf(sockaddr_in),
229 family: sa_family_t = AF_INET,
230 port: in_port_t,
231 addr: u32,
232 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
233};
234
235pub const sockaddr_in6 = extern struct {
236 len: u8 = @sizeOf(sockaddr_in6),
237 family: sa_family_t = AF_INET6,
238 port: in_port_t,
239 flowinfo: u32,
240 addr: [16]u8,
241 scope_id: u32,
242};
243
244/// Definitions for UNIX IPC domain.
245pub const sockaddr_un = extern struct {
246 /// total sockaddr length
247 len: u8 = @sizeOf(sockaddr_un),
248
249 /// AF_LOCAL
250 family: sa_family_t = AF_LOCAL,
251
252 /// path name
253 path: [104]u8,
254};
255
256/// get address to use bind()
257pub const AI_PASSIVE = 1;
258
259/// fill ai_canonname
260pub const AI_CANONNAME = 2;
261
262/// prevent host name resolution
263pub const AI_NUMERICHOST = 4;
264
265/// prevent service name resolution
266pub const AI_NUMERICSERV = 16;
267
268/// only if any address is assigned
269pub const AI_ADDRCONFIG = 64;
270
271pub const CTL_KERN = 1;
272pub const CTL_DEBUG = 5;
273
274pub const KERN_PROC_ARGS = 55;
275pub const KERN_PROC_ARGV = 1;
276
277pub const PATH_MAX = 1024;
278
279pub const STDIN_FILENO = 0;
280pub const STDOUT_FILENO = 1;
281pub const STDERR_FILENO = 2;
282
283pub const PROT_NONE = 0;
284pub const PROT_READ = 1;
285pub const PROT_WRITE = 2;
286pub const PROT_EXEC = 4;
287
288pub const CLOCK_REALTIME = 0;
289pub const CLOCK_PROCESS_CPUTIME_ID = 2;
290pub const CLOCK_MONOTONIC = 3;
291pub const CLOCK_THREAD_CPUTIME_ID = 4;
292
293pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
294pub const MAP_SHARED = 0x0001;
295pub const MAP_PRIVATE = 0x0002;
296pub const MAP_FIXED = 0x0010;
297pub const MAP_RENAME = 0;
298pub const MAP_NORESERVE = 0;
299pub const MAP_INHERIT = 0;
300pub const MAP_HASSEMAPHORE = 0;
301pub const MAP_TRYFIXED = 0;
302
303pub const MAP_FILE = 0;
304pub const MAP_ANON = 0x1000;
305pub const MAP_ANONYMOUS = MAP_ANON;
306pub const MAP_STACK = 0x4000;
307pub const MAP_CONCEAL = 0x8000;
308
309pub const WNOHANG = 1;
310pub const WUNTRACED = 2;
311pub const WCONTINUED = 8;
312
313pub const SA_ONSTACK = 0x0001;
314pub const SA_RESTART = 0x0002;
315pub const SA_RESETHAND = 0x0004;
316pub const SA_NOCLDSTOP = 0x0008;
317pub const SA_NODEFER = 0x0010;
318pub const SA_NOCLDWAIT = 0x0020;
319pub const SA_SIGINFO = 0x0040;
320
321pub const SIGHUP = 1;
322pub const SIGINT = 2;
323pub const SIGQUIT = 3;
324pub const SIGILL = 4;
325pub const SIGTRAP = 5;
326pub const SIGABRT = 6;
327pub const SIGIOT = SIGABRT;
328pub const SIGEMT = 7;
329pub const SIGFPE = 8;
330pub const SIGKILL = 9;
331pub const SIGBUS = 10;
332pub const SIGSEGV = 11;
333pub const SIGSYS = 12;
334pub const SIGPIPE = 13;
335pub const SIGALRM = 14;
336pub const SIGTERM = 15;
337pub const SIGURG = 16;
338pub const SIGSTOP = 17;
339pub const SIGTSTP = 18;
340pub const SIGCONT = 19;
341pub const SIGCHLD = 20;
342pub const SIGTTIN = 21;
343pub const SIGTTOU = 22;
344pub const SIGIO = 23;
345pub const SIGXCPU = 24;
346pub const SIGXFSZ = 25;
347pub const SIGVTALRM = 26;
348pub const SIGPROF = 27;
349pub const SIGWINCH = 28;
350pub const SIGINFO = 29;
351pub const SIGUSR1 = 30;
352pub const SIGUSR2 = 31;
353pub const SIGPWR = 32;
354
355// access function
356pub const F_OK = 0; // test for existence of file
357pub const X_OK = 1; // test for execute or search permission
358pub const W_OK = 2; // test for write permission
359pub const R_OK = 4; // test for read permission
360
361/// open for reading only
362pub const O_RDONLY = 0x00000000;
363
364/// open for writing only
365pub const O_WRONLY = 0x00000001;
366
367/// open for reading and writing
368pub const O_RDWR = 0x00000002;
369
370/// mask for above modes
371pub const O_ACCMODE = 0x00000003;
372
373/// no delay
374pub const O_NONBLOCK = 0x00000004;
375
376/// set append mode
377pub const O_APPEND = 0x00000008;
378
379/// open with shared file lock
380pub const O_SHLOCK = 0x00000010;
381
382/// open with exclusive file lock
383pub const O_EXLOCK = 0x00000020;
384
385/// signal pgrp when data ready
386pub const O_ASYNC = 0x00000040;
387
388/// synchronous writes
389pub const O_SYNC = 0x00000080;
390
391/// don't follow symlinks on the last
392pub const O_NOFOLLOW = 0x00000100;
393
394/// create if nonexistent
395pub const O_CREAT = 0x00000200;
396
397/// truncate to zero length
398pub const O_TRUNC = 0x00000400;
399
400/// error if already exists
401pub const O_EXCL = 0x00000800;
402
403/// don't assign controlling terminal
404pub const O_NOCTTY = 0x00008000;
405
406/// write: I/O data completion
407pub const O_DSYNC = O_SYNC;
408
409/// read: I/O completion as for write
410pub const O_RSYNC = O_SYNC;
411
412/// fail if not a directory
413pub const O_DIRECTORY = 0x20000;
414
415/// set close on exec
416pub const O_CLOEXEC = 0x10000;
417
418pub const F_DUPFD = 0;
419pub const F_GETFD = 1;
420pub const F_SETFD = 2;
421pub const F_GETFL = 3;
422pub const F_SETFL = 4;
423
424pub const F_GETOWN = 5;
425pub const F_SETOWN = 6;
426
427pub const F_GETLK = 7;
428pub const F_SETLK = 8;
429pub const F_SETLKW = 9;
430
431pub const F_RDLCK = 1;
432pub const F_UNLCK = 2;
433pub const F_WRLCK = 3;
434
435pub const LOCK_SH = 0x01;
436pub const LOCK_EX = 0x02;
437pub const LOCK_NB = 0x04;
438pub const LOCK_UN = 0x08;
439
440pub const FD_CLOEXEC = 1;
441
442pub const SEEK_SET = 0;
443pub const SEEK_CUR = 1;
444pub const SEEK_END = 2;
445
446pub const SIG_BLOCK = 1;
447pub const SIG_UNBLOCK = 2;
448pub const SIG_SETMASK = 3;
449
450pub const SOCK_STREAM = 1;
451pub const SOCK_DGRAM = 2;
452pub const SOCK_RAW = 3;
453pub const SOCK_RDM = 4;
454pub const SOCK_SEQPACKET = 5;
455
456pub const SOCK_CLOEXEC = 0x8000;
457pub const SOCK_NONBLOCK = 0x4000;
458
459pub const PF_UNSPEC = AF_UNSPEC;
460pub const PF_LOCAL = AF_LOCAL;
461pub const PF_UNIX = AF_UNIX;
462pub const PF_INET = AF_INET;
463pub const PF_APPLETALK = AF_APPLETALK;
464pub const PF_INET6 = AF_INET6;
465pub const PF_DECnet = AF_DECnet;
466pub const PF_KEY = AF_KEY;
467pub const PF_ROUTE = AF_ROUTE;
468pub const PF_SNA = AF_SNA;
469pub const PF_MPLS = AF_MPLS;
470pub const PF_BLUETOOTH = AF_BLUETOOTH;
471pub const PF_ISDN = AF_ISDN;
472pub const PF_MAX = AF_MAX;
473
474pub const AF_UNSPEC = 0;
475pub const AF_UNIX = 1;
476pub const AF_LOCAL = AF_UNIX;
477pub const AF_INET = 2;
478pub const AF_APPLETALK = 16;
479pub const AF_INET6 = 24;
480pub const AF_KEY = 30;
481pub const AF_ROUTE = 17;
482pub const AF_SNA = 11;
483pub const AF_MPLS = 33;
484pub const AF_BLUETOOTH = 32;
485pub const AF_ISDN = 26;
486pub const AF_MAX = 36;
487
488pub const DT_UNKNOWN = 0;
489pub const DT_FIFO = 1;
490pub const DT_CHR = 2;
491pub const DT_DIR = 4;
492pub const DT_BLK = 6;
493pub const DT_REG = 8;
494pub const DT_LNK = 10;
495pub const DT_SOCK = 12;
496pub const DT_WHT = 14; // XXX
497
498/// add event to kq (implies enable)
499pub const EV_ADD = 0x0001;
500
501/// delete event from kq
502pub const EV_DELETE = 0x0002;
503
504/// enable event
505pub const EV_ENABLE = 0x0004;
506
507/// disable event (not reported)
508pub const EV_DISABLE = 0x0008;
509
510/// only report one occurrence
511pub const EV_ONESHOT = 0x0010;
512
513/// clear event state after reporting
514pub const EV_CLEAR = 0x0020;
515
516/// force immediate event output
517/// ... with or without EV_ERROR
518/// ... use KEVENT_FLAG_ERROR_EVENTS
519/// on syscalls supporting flags
520pub const EV_RECEIPT = 0x0040;
521
522/// disable event after reporting
523pub const EV_DISPATCH = 0x0080;
524
525pub const EVFILT_READ = -1;
526pub const EVFILT_WRITE = -2;
527
528/// attached to aio requests
529pub const EVFILT_AIO = -3;
530
531/// attached to vnodes
532pub const EVFILT_VNODE = -4;
533
534/// attached to struct proc
535pub const EVFILT_PROC = -5;
536
537/// attached to struct proc
538pub const EVFILT_SIGNAL = -6;
539
540/// timers
541pub const EVFILT_TIMER = -7;
542
543/// devices
544pub const EVFILT_DEVICE = -8;
545
546/// low water mark
547pub const NOTE_LOWAT = 0x0001;
548
549/// return on EOF
550pub const NOTE_EOF = 0x0002;
551
552/// vnode was removed
553pub const NOTE_DELETE = 0x0001;
554
555/// data contents changed
556pub const NOTE_WRITE = 0x0002;
557
558/// size increased
559pub const NOTE_EXTEND = 0x0004;
560
561/// attributes changed
562pub const NOTE_ATTRIB = 0x0008;
563
564/// link count changed
565pub const NOTE_LINK = 0x0010;
566
567/// vnode was renamed
568pub const NOTE_RENAME = 0x0020;
569
570/// vnode access was revoked
571pub const NOTE_REVOKE = 0x0040;
572
573/// process exited
574pub const NOTE_EXIT = 0x80000000;
575
576/// process forked
577pub const NOTE_FORK = 0x40000000;
578
579/// process exec'd
580pub const NOTE_EXEC = 0x20000000;
581
582/// mask for signal & exit status
583pub const NOTE_PDATAMASK = 0x000fffff;
584pub const NOTE_PCTRLMASK = 0xf0000000;
585
586pub const TIOCCBRK = 0x2000747a;
587pub const TIOCCDTR = 0x20007478;
588pub const TIOCCONS = 0x80047462;
589pub const TIOCDCDTIMESTAMP = 0x40107458;
590pub const TIOCDRAIN = 0x2000745e;
591pub const TIOCEXCL = 0x2000740d;
592pub const TIOCEXT = 0x80047460;
593pub const TIOCFLAG_CDTRCTS = 0x10;
594pub const TIOCFLAG_CLOCAL = 0x2;
595pub const TIOCFLAG_CRTSCTS = 0x4;
596pub const TIOCFLAG_MDMBUF = 0x8;
597pub const TIOCFLAG_SOFTCAR = 0x1;
598pub const TIOCFLUSH = 0x80047410;
599pub const TIOCGETA = 0x402c7413;
600pub const TIOCGETD = 0x4004741a;
601pub const TIOCGFLAGS = 0x4004745d;
602pub const TIOCGLINED = 0x40207442;
603pub const TIOCGPGRP = 0x40047477;
604pub const TIOCGQSIZE = 0x40047481;
605pub const TIOCGRANTPT = 0x20007447;
606pub const TIOCGSID = 0x40047463;
607pub const TIOCGSIZE = 0x40087468;
608pub const TIOCGWINSZ = 0x40087468;
609pub const TIOCMBIC = 0x8004746b;
610pub const TIOCMBIS = 0x8004746c;
611pub const TIOCMGET = 0x4004746a;
612pub const TIOCMSET = 0x8004746d;
613pub const TIOCM_CAR = 0x40;
614pub const TIOCM_CD = 0x40;
615pub const TIOCM_CTS = 0x20;
616pub const TIOCM_DSR = 0x100;
617pub const TIOCM_DTR = 0x2;
618pub const TIOCM_LE = 0x1;
619pub const TIOCM_RI = 0x80;
620pub const TIOCM_RNG = 0x80;
621pub const TIOCM_RTS = 0x4;
622pub const TIOCM_SR = 0x10;
623pub const TIOCM_ST = 0x8;
624pub const TIOCNOTTY = 0x20007471;
625pub const TIOCNXCL = 0x2000740e;
626pub const TIOCOUTQ = 0x40047473;
627pub const TIOCPKT = 0x80047470;
628pub const TIOCPKT_DATA = 0x0;
629pub const TIOCPKT_DOSTOP = 0x20;
630pub const TIOCPKT_FLUSHREAD = 0x1;
631pub const TIOCPKT_FLUSHWRITE = 0x2;
632pub const TIOCPKT_IOCTL = 0x40;
633pub const TIOCPKT_NOSTOP = 0x10;
634pub const TIOCPKT_START = 0x8;
635pub const TIOCPKT_STOP = 0x4;
636pub const TIOCPTMGET = 0x40287446;
637pub const TIOCPTSNAME = 0x40287448;
638pub const TIOCRCVFRAME = 0x80087445;
639pub const TIOCREMOTE = 0x80047469;
640pub const TIOCSBRK = 0x2000747b;
641pub const TIOCSCTTY = 0x20007461;
642pub const TIOCSDTR = 0x20007479;
643pub const TIOCSETA = 0x802c7414;
644pub const TIOCSETAF = 0x802c7416;
645pub const TIOCSETAW = 0x802c7415;
646pub const TIOCSETD = 0x8004741b;
647pub const TIOCSFLAGS = 0x8004745c;
648pub const TIOCSIG = 0x2000745f;
649pub const TIOCSLINED = 0x80207443;
650pub const TIOCSPGRP = 0x80047476;
651pub const TIOCSQSIZE = 0x80047480;
652pub const TIOCSSIZE = 0x80087467;
653pub const TIOCSTART = 0x2000746e;
654pub const TIOCSTAT = 0x80047465;
655pub const TIOCSTI = 0x80017472;
656pub const TIOCSTOP = 0x2000746f;
657pub const TIOCSWINSZ = 0x80087467;
658pub const TIOCUCNTL = 0x80047466;
659pub const TIOCXMTFRAME = 0x80087444;
660
661pub fn WEXITSTATUS(s: u32) u32 {
662 return (s >> 8) & 0xff;
663}
664pub fn WTERMSIG(s: u32) u32 {
665 return (s & 0x7f);
666}
667pub fn WSTOPSIG(s: u32) u32 {
668 return WEXITSTATUS(s);
669}
670pub fn WIFEXITED(s: u32) bool {
671 return WTERMSIG(s) == 0;
672}
673
674pub fn WIFCONTINUED(s: u32) bool {
675 return ((s & 0o177777) == 0o177777);
676}
677
678pub fn WIFSTOPPED(s: u32) bool {
679 return (s & 0xff == 0o177);
680}
681
682pub fn WIFSIGNALED(s: u32) bool {
683 return (((s) & 0o177) != 0o177) and (((s) & 0o177) != 0);
684}
685
686pub const winsize = extern struct {
687 ws_row: u16,
688 ws_col: u16,
689 ws_xpixel: u16,
690 ws_ypixel: u16,
691};
692
693const NSIG = 33;
694
695pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
696pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
697pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
698
699/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
700pub const Sigaction = extern struct {
701 pub const sigaction_fn = fn (c_int, *siginfo_t, ?*c_void) callconv(.C) void;
702 /// signal handler
703 sigaction: ?sigaction_fn,
704 /// signal mask to apply
705 mask: sigset_t,
706 /// signal options
707 flags: c_int,
708};
709
710pub const sigval = extern union {
711 int: c_int,
712 ptr: ?*c_void,
713};
714
715pub const siginfo_t = extern union {
716 pad: [128]u8,
717 info: _ksiginfo,
718};
719
720pub const _ksiginfo = extern struct {
721 signo: c_int,
722 code: c_int,
723 errno: c_int,
724 data: extern union {
725 proc: extern struct {
726 pid: pid_t,
727 uid: uid_t,
728 value: sigval,
729 utime: clock_t,
730 stime: clock_t,
731 status: c_int,
732 },
733 fault: extern struct {
734 addr: ?*c_void,
735 trapno: c_int,
736 },
737 } align(@sizeOf(usize)),
738};
739
740pub const sigset_t = c_uint;
741pub const empty_sigset = sigset_t(0);
742
743pub const EPERM = 1; // Operation not permitted
744pub const ENOENT = 2; // No such file or directory
745pub const ESRCH = 3; // No such process
746pub const EINTR = 4; // Interrupted system call
747pub const EIO = 5; // Input/output error
748pub const ENXIO = 6; // Device not configured
749pub const E2BIG = 7; // Argument list too long
750pub const ENOEXEC = 8; // Exec format error
751pub const EBADF = 9; // Bad file descriptor
752pub const ECHILD = 10; // No child processes
753pub const EDEADLK = 11; // Resource deadlock avoided
754// 11 was EAGAIN
755pub const ENOMEM = 12; // Cannot allocate memory
756pub const EACCES = 13; // Permission denied
757pub const EFAULT = 14; // Bad address
758pub const ENOTBLK = 15; // Block device required
759pub const EBUSY = 16; // Device busy
760pub const EEXIST = 17; // File exists
761pub const EXDEV = 18; // Cross-device link
762pub const ENODEV = 19; // Operation not supported by device
763pub const ENOTDIR = 20; // Not a directory
764pub const EISDIR = 21; // Is a directory
765pub const EINVAL = 22; // Invalid argument
766pub const ENFILE = 23; // Too many open files in system
767pub const EMFILE = 24; // Too many open files
768pub const ENOTTY = 25; // Inappropriate ioctl for device
769pub const ETXTBSY = 26; // Text file busy
770pub const EFBIG = 27; // File too large
771pub const ENOSPC = 28; // No space left on device
772pub const ESPIPE = 29; // Illegal seek
773pub const EROFS = 30; // Read-only file system
774pub const EMLINK = 31; // Too many links
775pub const EPIPE = 32; // Broken pipe
776
777// math software
778pub const EDOM = 33; // Numerical argument out of domain
779pub const ERANGE = 34; // Result too large or too small
780
781// non-blocking and interrupt i/o
782pub const EAGAIN = 35; // Resource temporarily unavailable
783pub const EWOULDBLOCK = EAGAIN; // Operation would block
784pub const EINPROGRESS = 36; // Operation now in progress
785pub const EALREADY = 37; // Operation already in progress
786
787// ipc/network software -- argument errors
788pub const ENOTSOCK = 38; // Socket operation on non-socket
789pub const EDESTADDRREQ = 39; // Destination address required
790pub const EMSGSIZE = 40; // Message too long
791pub const EPROTOTYPE = 41; // Protocol wrong type for socket
792pub const ENOPROTOOPT = 42; // Protocol option not available
793pub const EPROTONOSUPPORT = 43; // Protocol not supported
794pub const ESOCKTNOSUPPORT = 44; // Socket type not supported
795pub const EOPNOTSUPP = 45; // Operation not supported
796pub const EPFNOSUPPORT = 46; // Protocol family not supported
797pub const EAFNOSUPPORT = 47; // Address family not supported by protocol family
798pub const EADDRINUSE = 48; // Address already in use
799pub const EADDRNOTAVAIL = 49; // Can't assign requested address
800
801// ipc/network software -- operational errors
802pub const ENETDOWN = 50; // Network is down
803pub const ENETUNREACH = 51; // Network is unreachable
804pub const ENETRESET = 52; // Network dropped connection on reset
805pub const ECONNABORTED = 53; // Software caused connection abort
806pub const ECONNRESET = 54; // Connection reset by peer
807pub const ENOBUFS = 55; // No buffer space available
808pub const EISCONN = 56; // Socket is already connected
809pub const ENOTCONN = 57; // Socket is not connected
810pub const ESHUTDOWN = 58; // Can't send after socket shutdown
811pub const ETOOMANYREFS = 59; // Too many references: can't splice
812pub const ETIMEDOUT = 60; // Operation timed out
813pub const ECONNREFUSED = 61; // Connection refused
814
815pub const ELOOP = 62; // Too many levels of symbolic links
816pub const ENAMETOOLONG = 63; // File name too long
817
818// should be rearranged
819pub const EHOSTDOWN = 64; // Host is down
820pub const EHOSTUNREACH = 65; // No route to host
821pub const ENOTEMPTY = 66; // Directory not empty
822
823// quotas & mush
824pub const EPROCLIM = 67; // Too many processes
825pub const EUSERS = 68; // Too many users
826pub const EDQUOT = 69; // Disc quota exceeded
827
828// Network File System
829pub const ESTALE = 70; // Stale NFS file handle
830pub const EREMOTE = 71; // Too many levels of remote in path
831pub const EBADRPC = 72; // RPC struct is bad
832pub const ERPCMISMATCH = 73; // RPC version wrong
833pub const EPROGUNAVAIL = 74; // RPC prog. not avail
834pub const EPROGMISMATCH = 75; // Program version wrong
835pub const EPROCUNAVAIL = 76; // Bad procedure for program
836
837pub const ENOLCK = 77; // No locks available
838pub const ENOSYS = 78; // Function not implemented
839
840pub const EFTYPE = 79; // Inappropriate file type or format
841pub const EAUTH = 80; // Authentication error
842pub const ENEEDAUTH = 81; // Need authenticator
843pub const EIPSEC = 82; // IPsec processing failure
844pub const ENOATTR = 83; // Attribute not found
845
846// Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995
847pub const EILSEQ = 84; // Illegal byte sequence
848
849pub const ENOMEDIUM = 85; // No medium found
850pub const EMEDIUMTYPE = 86; // Wrong medium type
851pub const EOVERFLOW = 87; // Value too large to be stored in data type
852pub const ECANCELED = 88; // Operation canceled
853pub const EIDRM = 89; // Identifier removed
854pub const ENOMSG = 90; // No message of desired type
855pub const ENOTSUP = 91; // Not supported
856pub const EBADMSG = 92; // Bad or Corrupt message
857pub const ENOTRECOVERABLE = 93; // State not recoverable
858pub const EOWNERDEAD = 94; // Previous owner died
859pub const EPROTO = 95; // Protocol error
860
861pub const ELAST = 95; // Must equal largest errno
862
863const _MAX_PAGE_SHIFT = switch (builtin.arch) {
864 .i386 => 12,
865 .sparcv9 => 13,
866};
867pub const MINSIGSTKSZ = 1 << _MAX_PAGE_SHIFT;
868pub const SIGSTKSZ = MINSIGSTKSZ + (1 << _MAX_PAGE_SHIFT) * 4;
869
870pub const SS_ONSTACK = 0x0001;
871pub const SS_DISABLE = 0x0004;
872
873pub const stack_t = extern struct {
874 ss_sp: [*]u8,
875 ss_size: usize,
876 ss_flags: c_int,
877};
878
879pub const S_IFMT = 0o170000;
880
881pub const S_IFIFO = 0o010000;
882pub const S_IFCHR = 0o020000;
883pub const S_IFDIR = 0o040000;
884pub const S_IFBLK = 0o060000;
885pub const S_IFREG = 0o100000;
886pub const S_IFLNK = 0o120000;
887pub const S_IFSOCK = 0o140000;
888
889pub const S_ISUID = 0o4000;
890pub const S_ISGID = 0o2000;
891pub const S_ISVTX = 0o1000;
892pub const S_IRWXU = 0o700;
893pub const S_IRUSR = 0o400;
894pub const S_IWUSR = 0o200;
895pub const S_IXUSR = 0o100;
896pub const S_IRWXG = 0o070;
897pub const S_IRGRP = 0o040;
898pub const S_IWGRP = 0o020;
899pub const S_IXGRP = 0o010;
900pub const S_IRWXO = 0o007;
901pub const S_IROTH = 0o004;
902pub const S_IWOTH = 0o002;
903pub const S_IXOTH = 0o001;
904
905pub fn S_ISFIFO(m: u32) bool {
906 return m & S_IFMT == S_IFIFO;
907}
908
909pub fn S_ISCHR(m: u32) bool {
910 return m & S_IFMT == S_IFCHR;
911}
912
913pub fn S_ISDIR(m: u32) bool {
914 return m & S_IFMT == S_IFDIR;
915}
916
917pub fn S_ISBLK(m: u32) bool {
918 return m & S_IFMT == S_IFBLK;
919}
920
921pub fn S_ISREG(m: u32) bool {
922 return m & S_IFMT == S_IFREG;
923}
924
925pub fn S_ISLNK(m: u32) bool {
926 return m & S_IFMT == S_IFLNK;
927}
928
929pub fn S_ISSOCK(m: u32) bool {
930 return m & S_IFMT == S_IFSOCK;
931}
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.
936pub const AT_FDCWD = -100;
937
938/// Check access using effective user and group ID
939pub const AT_EACCESS = 0x01;
940
941/// Do not follow symbolic links
942pub const AT_SYMLINK_NOFOLLOW = 0x02;
943
944/// Follow symbolic link
945pub const AT_SYMLINK_FOLLOW = 0x04;
946
947/// Remove directory instead of file
948pub const AT_REMOVEDIR = 0x08;
949
950pub const HOST_NAME_MAX = 255;
951
952/// dummy for IP
953pub const IPPROTO_IP = 0;
954
955/// IP6 hop-by-hop options
956pub const IPPROTO_HOPOPTS = IPPROTO_IP;
957
958/// control message protocol
959pub const IPPROTO_ICMP = 1;
960
961/// group mgmt protocol
962pub const IPPROTO_IGMP = 2;
963
964/// gateway^2 (deprecated)
965pub const IPPROTO_GGP = 3;
966
967/// IP header
968pub const IPPROTO_IPV4 = IPPROTO_IPIP;
969
970/// IP inside IP
971pub const IPPROTO_IPIP = 4;
972
973/// tcp
974pub const IPPROTO_TCP = 6;
975
976/// exterior gateway protocol
977pub const IPPROTO_EGP = 8;
978
979/// pup
980pub const IPPROTO_PUP = 12;
981
982/// user datagram protocol
983pub const IPPROTO_UDP = 17;
984
985/// xns idp
986pub const IPPROTO_IDP = 22;
987
988/// tp-4 w/ class negotiation
989pub const IPPROTO_TP = 29;
990
991/// IP6 header
992pub const IPPROTO_IPV6 = 41;
993
994/// IP6 routing header
995pub const IPPROTO_ROUTING = 43;
996
997/// IP6 fragmentation header
998pub const IPPROTO_FRAGMENT = 44;
999
1000/// resource reservation
1001pub const IPPROTO_RSVP = 46;
1002
1003/// GRE encaps RFC 1701
1004pub const IPPROTO_GRE = 47;
1005
1006/// encap. security payload
1007pub const IPPROTO_ESP = 50;
1008
1009/// authentication header
1010pub const IPPROTO_AH = 51;
1011
1012/// IP Mobility RFC 2004
1013pub const IPPROTO_MOBILE = 55;
1014
1015/// IPv6 ICMP
1016pub const IPPROTO_IPV6_ICMP = 58;
1017
1018/// ICMP6
1019pub const IPPROTO_ICMPV6 = 58;
1020
1021/// IP6 no next header
1022pub const IPPROTO_NONE = 59;
1023
1024/// IP6 destination option
1025pub const IPPROTO_DSTOPTS = 60;
1026
1027/// ISO cnlp
1028pub const IPPROTO_EON = 80;
1029
1030/// Ethernet-in-IP
1031pub const IPPROTO_ETHERIP = 97;
1032
1033/// encapsulation header
1034pub const IPPROTO_ENCAP = 98;
1035
1036/// Protocol indep. multicast
1037pub const IPPROTO_PIM = 103;
1038
1039/// IP Payload Comp. Protocol
1040pub const IPPROTO_IPCOMP = 108;
1041
1042/// VRRP RFC 2338
1043pub const IPPROTO_VRRP = 112;
1044
1045/// Common Address Resolution Protocol
1046pub const IPPROTO_CARP = 112;
1047
1048/// PFSYNC
1049pub const IPPROTO_PFSYNC = 240;
1050
1051/// raw IP packet
1052pub const IPPROTO_RAW = 255;
lib/std/os/openbsd.zig created+8
...@@ -0,0 +1,8 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2020 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("../std.zig");
7pub usingnamespace std.c;
8pub usingnamespace @import("bits.zig");
lib/std/packed_int_array.zig+2-2
...@@ -618,7 +618,7 @@ test "PackedIntArray at end of available memory" {...@@ -618,7 +618,7 @@ test "PackedIntArray at end of available memory" {
618 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;618 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
619619
620 switch (builtin.os.tag) {620 switch (builtin.os.tag) {
621 .linux, .macos, .ios, .freebsd, .netbsd, .windows => {},621 .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
622 else => return,622 else => return,
623 }623 }
624 const PackedArray = PackedIntArray(u3, 8);624 const PackedArray = PackedIntArray(u3, 8);
...@@ -639,7 +639,7 @@ test "PackedIntSlice at end of available memory" {...@@ -639,7 +639,7 @@ test "PackedIntSlice at end of available memory" {
639 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;639 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
640640
641 switch (builtin.os.tag) {641 switch (builtin.os.tag) {
642 .linux, .macos, .ios, .freebsd, .netbsd, .windows => {},642 .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
643 else => return,643 else => return,
644 }644 }
645 const PackedSlice = PackedIntSlice(u11);645 const PackedSlice = PackedIntSlice(u11);
lib/std/process.zig+2-1
...@@ -585,7 +585,7 @@ pub const UserInfo = struct {...@@ -585,7 +585,7 @@ pub const UserInfo = struct {
585/// POSIX function which gets a uid from username.585/// POSIX function which gets a uid from username.
586pub fn getUserInfo(name: []const u8) !UserInfo {586pub fn getUserInfo(name: []const u8) !UserInfo {
587 return switch (builtin.os.tag) {587 return switch (builtin.os.tag) {
588 .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd => posixGetUserInfo(name),588 .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd => posixGetUserInfo(name),
589 else => @compileError("Unsupported OS"),589 else => @compileError("Unsupported OS"),
590 };590 };
591}591}
...@@ -712,6 +712,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]...@@ -712,6 +712,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
712 .freebsd,712 .freebsd,
713 .netbsd,713 .netbsd,
714 .dragonfly,714 .dragonfly,
715 .openbsd,
715 => {716 => {
716 var paths = List.init(allocator);717 var paths = List.init(allocator);
717 errdefer {718 errdefer {
lib/std/target.zig+3-3
...@@ -266,8 +266,8 @@ pub const Target = struct {...@@ -266,8 +266,8 @@ pub const Target = struct {
266 },266 },
267 .openbsd => return .{267 .openbsd => return .{
268 .semver = .{268 .semver = .{
269 .min = .{ .major = 6, .minor = 6 },269 .min = .{ .major = 6, .minor = 8 },
270 .max = .{ .major = 6, .minor = 6 },270 .max = .{ .major = 6, .minor = 8 },
271 },271 },
272 },272 },
273 .dragonfly => return .{273 .dragonfly => return .{
...@@ -1362,6 +1362,7 @@ pub const Target = struct {...@@ -1362,6 +1362,7 @@ pub const Target = struct {
1362 switch (self.os.tag) {1362 switch (self.os.tag) {
1363 .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),1363 .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),
1364 .netbsd => return copy(&result, "/libexec/ld.elf_so"),1364 .netbsd => return copy(&result, "/libexec/ld.elf_so"),
1365 .openbsd => return copy(&result, "/libexec/ld.so"),
1365 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),1366 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
1366 .linux => switch (self.cpu.arch) {1367 .linux => switch (self.cpu.arch) {
1367 .i386,1368 .i386,
...@@ -1471,7 +1472,6 @@ pub const Target = struct {...@@ -1471,7 +1472,6 @@ pub const Target = struct {
1471 .fuchsia,1472 .fuchsia,
1472 .kfreebsd,1473 .kfreebsd,
1473 .lv2,1474 .lv2,
1474 .openbsd,
1475 .solaris,1475 .solaris,
1476 .haiku,1476 .haiku,
1477 .minix,1477 .minix,
lib/std/zig/cross_target.zig+4
...@@ -449,6 +449,10 @@ pub const CrossTarget = struct {...@@ -449,6 +449,10 @@ pub const CrossTarget = struct {
449 return self.getOsTag() == .netbsd;449 return self.getOsTag() == .netbsd;
450 }450 }
451451
452 pub fn isOpenBSD(self: CrossTarget) bool {
453 return self.getOsTag() == .openbsd;
454 }
455
452 pub fn isUefi(self: CrossTarget) bool {456 pub fn isUefi(self: CrossTarget) bool {
453 return self.getOsTag() == .uefi;457 return self.getOsTag() == .uefi;
454 }458 }
src/libc_installation.zig+1-1
...@@ -196,7 +196,7 @@ pub const LibCInstallation = struct {...@@ -196,7 +196,7 @@ pub const LibCInstallation = struct {
196 errdefer batch.wait() catch {};196 errdefer batch.wait() catch {};
197 batch.add(&async self.findNativeIncludeDirPosix(args));197 batch.add(&async self.findNativeIncludeDirPosix(args));
198 switch (Target.current.os.tag) {198 switch (Target.current.os.tag) {
199 .freebsd, .netbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),199 .freebsd, .netbsd, .openbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
200 .linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),200 .linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),
201 else => {},201 else => {},
202 }202 }
src/link/Elf.zig+6-1
...@@ -1432,7 +1432,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1432,7 +1432,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
14321432
1433 if (link_in_crt) {1433 if (link_in_crt) {
1434 const crt1o: []const u8 = o: {1434 const crt1o: []const u8 = o: {
1435 if (target.os.tag == .netbsd) {1435 if (target.os.tag == .netbsd or target.os.tag == .openbsd) {
1436 break :o "crt0.o";1436 break :o "crt0.o";
1437 } else if (target.isAndroid()) {1437 } else if (target.isAndroid()) {
1438 if (self.base.options.link_mode == .Dynamic) {1438 if (self.base.options.link_mode == .Dynamic) {
...@@ -1450,6 +1450,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1450,6 +1450,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1450 if (target_util.libc_needs_crti_crtn(target)) {1450 if (target_util.libc_needs_crti_crtn(target)) {
1451 try argv.append(try comp.get_libc_crt_file(arena, "crti.o"));1451 try argv.append(try comp.get_libc_crt_file(arena, "crti.o"));
1452 }1452 }
1453 if (target.os.tag == .openbsd) {
1454 try argv.append(try comp.get_libc_crt_file(arena, "crtbegin.o"));
1455 }
1453 }1456 }
14541457
1455 // rpaths1458 // rpaths
...@@ -1594,6 +1597,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1594,6 +1597,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1594 if (link_in_crt) {1597 if (link_in_crt) {
1595 if (target.isAndroid()) {1598 if (target.isAndroid()) {
1596 try argv.append(try comp.get_libc_crt_file(arena, "crtend_android.o"));1599 try argv.append(try comp.get_libc_crt_file(arena, "crtend_android.o"));
1600 } else if (target.os.tag == .openbsd) {
1601 try argv.append(try comp.get_libc_crt_file(arena, "crtend.o"));
1597 } else if (target_util.libc_needs_crti_crtn(target)) {1602 } else if (target_util.libc_needs_crti_crtn(target)) {
1598 try argv.append(try comp.get_libc_crt_file(arena, "crtn.o"));1603 try argv.append(try comp.get_libc_crt_file(arena, "crtn.o"));
1599 }1604 }
src/stage1.zig+3-1
...@@ -25,7 +25,9 @@ comptime {...@@ -25,7 +25,9 @@ comptime {
25pub const log = stage2.log;25pub const log = stage2.log;
26pub const log_level = stage2.log_level;26pub const log_level = stage2.log_level;
2727
28pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {28pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {
29 std.os.argv = argv[0..@intCast(usize, argc)];
30
29 std.debug.maybeEnableSegfaultHandler();31 std.debug.maybeEnableSegfaultHandler();
3032
31 zig_stage1_os_init();33 zig_stage1_os_init();
src/stage1/os.cpp+2-2
...@@ -59,7 +59,7 @@ typedef SSIZE_T ssize_t;...@@ -59,7 +59,7 @@ typedef SSIZE_T ssize_t;
5959
60#endif60#endif
6161
62#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY)62#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD)
63#include <link.h>63#include <link.h>
64#endif64#endif
6565
...@@ -67,7 +67,7 @@ typedef SSIZE_T ssize_t;...@@ -67,7 +67,7 @@ typedef SSIZE_T ssize_t;
67#include <sys/auxv.h>67#include <sys/auxv.h>
68#endif68#endif
6969
70#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY)70#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD)
71#include <sys/sysctl.h>71#include <sys/sysctl.h>
72#endif72#endif
7373
src/stage1/os.hpp+2
...@@ -29,6 +29,8 @@...@@ -29,6 +29,8 @@
29#define ZIG_OS_NETBSD29#define ZIG_OS_NETBSD
30#elif defined(__DragonFly__)30#elif defined(__DragonFly__)
31#define ZIG_OS_DRAGONFLY31#define ZIG_OS_DRAGONFLY
32#elif defined(__OpenBSD__)
33#define ZIG_OS_OPENBSD
32#else34#else
33#define ZIG_OS_UNKNOWN35#define ZIG_OS_UNKNOWN
34#endif36#endif
src/target.zig+3-3
...@@ -123,7 +123,7 @@ pub fn cannotDynamicLink(target: std.Target) bool {...@@ -123,7 +123,7 @@ pub fn cannotDynamicLink(target: std.Target) bool {
123/// since this is the stable syscall interface.123/// since this is the stable syscall interface.
124pub fn osRequiresLibC(target: std.Target) bool {124pub fn osRequiresLibC(target: std.Target) bool {
125 return switch (target.os.tag) {125 return switch (target.os.tag) {
126 .freebsd, .netbsd, .dragonfly, .macos, .ios, .watchos, .tvos => true,126 .freebsd, .netbsd, .dragonfly, .openbsd, .macos, .ios, .watchos, .tvos => true,
127 else => false,127 else => false,
128 };128 };
129}129}
...@@ -143,7 +143,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {...@@ -143,7 +143,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
143}143}
144144
145pub fn requiresPIE(target: std.Target) bool {145pub fn requiresPIE(target: std.Target) bool {
146 return target.isAndroid() or target.isDarwin();146 return target.isAndroid() or target.isDarwin() or target.os.tag == .openbsd;
147}147}
148148
149/// This function returns whether non-pic code is completely invalid on the given target.149/// This function returns whether non-pic code is completely invalid on the given target.
...@@ -161,7 +161,7 @@ pub fn supports_fpic(target: std.Target) bool {...@@ -161,7 +161,7 @@ pub fn supports_fpic(target: std.Target) bool {
161}161}
162162
163pub fn libc_needs_crti_crtn(target: std.Target) bool {163pub fn libc_needs_crti_crtn(target: std.Target) bool {
164 return !(target.cpu.arch.isRISCV() or target.isAndroid());164 return !(target.cpu.arch.isRISCV() or target.isAndroid() or target.os.tag == .openbsd);
165}165}
166166
167pub fn isSingleThreaded(target: std.Target) bool {167pub fn isSingleThreaded(target: std.Target) bool {