authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 17:34:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 17:34:43-07:00
log03f7cffce9472125f7a6e3c757309b8b841065fe
tree6e29e2289709ef3decedd685973198f023ecd559
parent9052e0b1377e4c4cd23b979b4a486df27a3444bd
parent35a7247a2c9ab208d96fdc9a7c0c63f4c852666c

Merge branch 'openbsd-minimal' of https://github.com/semarie/zig into semarie-openbsd-minimal


22 files changed, 1195 insertions(+), 45 deletions(-)

lib/std/c.zig+1-1
......@@ -249,7 +249,7 @@ pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
249249pub extern "c" fn malloc(usize) ?*c_void;
250250
251251pub usingnamespace switch (builtin.os.tag) {
252 .linux, .freebsd, .kfreebsd, .netbsd, .openbsd => struct {
252 .linux, .freebsd, .kfreebsd, .netbsd => struct {
253253 pub extern "c" fn malloc_usable_size(?*const c_void) usize;
254254 },
255255 .macos, .ios, .watchos, .tvos => struct {
lib/std/c/openbsd.zig+23
......@@ -3,9 +3,32 @@
33// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
44// The MIT license requires this copyright notice to be included in all copies
55// 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
622pub const pthread_mutex_t = extern struct {
723 inner: ?*c_void = null,
824};
925pub const pthread_cond_t = extern struct {
1026 inner: ?*c_void = null,
1127};
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 {
654654 .freebsd,
655655 .netbsd,
656656 .dragonfly,
657 .openbsd,
657658 .macos,
658659 .windows,
659660 => return DebugInfo.init(allocator),
......@@ -1640,7 +1641,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
16401641 };
16411642 }
16421643 },
1643 .linux, .netbsd, .freebsd, .dragonfly => struct {
1644 .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct {
16441645 base_address: usize,
16451646 dwarf: DW.DwarfInfo,
16461647 mapped_memory: []const u8,
lib/std/dynamic_library.zig+2-2
......@@ -19,7 +19,7 @@ const max = std.math.max;
1919pub const DynLib = switch (builtin.os.tag) {
2020 .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
2121 .windows => WindowsDynLib,
22 .macos, .tvos, .watchos, .ios, .freebsd => DlDynlib,
22 .macos, .tvos, .watchos, .ios, .freebsd, .openbsd => DlDynlib,
2323 else => void,
2424};
2525
......@@ -402,7 +402,7 @@ pub const DlDynlib = struct {
402402
403403test "dynamic_library" {
404404 const libname = switch (builtin.os.tag) {
405 .linux, .freebsd => "invalid_so.so",
405 .linux, .freebsd, .openbsd => "invalid_so.so",
406406 .windows => "invalid_dll.dll",
407407 .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",
408408 else => return error.SkipZigTest,
lib/std/event/loop.zig+12-11
......@@ -69,7 +69,7 @@ pub const Loop = struct {
6969 };
7070
7171 pub const EventFd = switch (builtin.os.tag) {
72 .macos, .freebsd, .netbsd, .dragonfly => KEventFd,
72 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventFd,
7373 .linux => struct {
7474 base: ResumeNode,
7575 epoll_op: u32,
......@@ -88,7 +88,7 @@ pub const Loop = struct {
8888 };
8989
9090 pub const Basic = switch (builtin.os.tag) {
91 .macos, .freebsd, .netbsd, .dragonfly => KEventBasic,
91 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventBasic,
9292 .linux => struct {
9393 base: ResumeNode,
9494 },
......@@ -266,7 +266,7 @@ pub const Loop = struct {
266266 self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);
267267 }
268268 },
269 .macos, .freebsd, .netbsd, .dragonfly => {
269 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
270270 self.os_data.kqfd = try os.kqueue();
271271 errdefer os.close(self.os_data.kqfd);
272272
......@@ -391,7 +391,7 @@ pub const Loop = struct {
391391 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
392392 os.close(self.os_data.epollfd);
393393 },
394 .macos, .freebsd, .netbsd, .dragonfly => {
394 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
395395 os.close(self.os_data.kqfd);
396396 },
397397 .windows => {
......@@ -485,7 +485,7 @@ pub const Loop = struct {
485485 .linux => {
486486 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN);
487487 },
488 .macos, .freebsd, .netbsd, .dragonfly => {
488 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
489489 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
490490 },
491491 else => @compileError("Unsupported OS"),
......@@ -497,7 +497,7 @@ pub const Loop = struct {
497497 .linux => {
498498 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT);
499499 },
500 .macos, .freebsd, .netbsd, .dragonfly => {
500 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
501501 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
502502 },
503503 else => @compileError("Unsupported OS"),
......@@ -509,7 +509,7 @@ pub const Loop = struct {
509509 .linux => {
510510 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
511511 },
512 .macos, .freebsd, .netbsd, .dragonfly => {
512 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
513513 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
514514 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
515515 },
......@@ -578,7 +578,7 @@ pub const Loop = struct {
578578 const eventfd_node = &resume_stack_node.data;
579579 eventfd_node.base.handle = next_tick_node.data;
580580 switch (builtin.os.tag) {
581 .macos, .freebsd, .netbsd, .dragonfly => {
581 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
582582 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
583583 const empty_kevs = &[0]os.Kevent{};
584584 _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
......@@ -644,6 +644,7 @@ pub const Loop = struct {
644644 .freebsd,
645645 .netbsd,
646646 .dragonfly,
647 .openbsd,
647648 => self.fs_thread.wait(),
648649 else => {},
649650 }
......@@ -736,7 +737,7 @@ pub const Loop = struct {
736737 }
737738 return;
738739 },
739 .macos, .freebsd, .netbsd, .dragonfly => {
740 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
740741 const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
741742 const empty_kevs = &[0]os.Kevent{};
742743 // cannot fail because we already added it and this just enables it
......@@ -1351,7 +1352,7 @@ pub const Loop = struct {
13511352 }
13521353 }
13531354 },
1354 .macos, .freebsd, .netbsd, .dragonfly => {
1355 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
13551356 var eventlist: [1]os.Kevent = undefined;
13561357 const empty_kevs = &[0]os.Kevent{};
13571358 const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
......@@ -1477,7 +1478,7 @@ pub const Loop = struct {
14771478
14781479 const OsData = switch (builtin.os.tag) {
14791480 .linux => LinuxOsData,
1480 .macos, .freebsd, .netbsd, .dragonfly => KEventData,
1481 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventData,
14811482 .windows => struct {
14821483 io_port: windows.HANDLE,
14831484 extra_thread_count: usize,
lib/std/fs.zig+43-5
......@@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
3939/// fit into a UTF-8 encoded array of this length.
4040/// The byte count includes room for a null sentinel byte.
4141pub 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,
4343 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
4444 // If it would require 4 UTF-8 bytes, then there would be a surrogate
4545 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
......@@ -303,7 +303,7 @@ pub const Dir = struct {
303303 const IteratorError = error{AccessDenied} || os.UnexpectedError;
304304
305305 pub const Iterator = switch (builtin.os.tag) {
306 .macos, .ios, .freebsd, .netbsd, .dragonfly => struct {
306 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
307307 dir: Dir,
308308 seek: i64,
309309 buf: [8192]u8, // TODO align(@alignOf(os.dirent)),
......@@ -319,7 +319,7 @@ pub const Dir = struct {
319319 pub fn next(self: *Self) Error!?Entry {
320320 switch (builtin.os.tag) {
321321 .macos, .ios => return self.nextDarwin(),
322 .freebsd, .netbsd, .dragonfly => return self.nextBsd(),
322 .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
323323 else => @compileError("unimplemented"),
324324 }
325325 }
......@@ -615,7 +615,7 @@ pub const Dir = struct {
615615
616616 pub fn iterate(self: Dir) Iterator {
617617 switch (builtin.os.tag) {
618 .macos, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{
618 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => return Iterator{
619619 .dir = self,
620620 .seek = 0,
621621 .index = 0,
......@@ -1302,7 +1302,7 @@ pub const Dir = struct {
13021302 error.AccessDenied => |e| switch (builtin.os.tag) {
13031303 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
13041304 // we need to handle that case specifically and translate the error
1305 .macos, .ios, .freebsd, .netbsd, .dragonfly => {
1305 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
13061306 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
13071307 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e;
13081308 const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;
......@@ -2232,6 +2232,44 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
22322232 // TODO could this slice from 0 to out_len instead?
22332233 return mem.spanZ(@ptrCast([*:0]u8, out_buffer));
22342234 },
2235 .openbsd => {
2236 // OpenBSD doesn't support getting the path of a running process, so try to guess it
2237 if (os.argv.len >= 1) {
2238 const argv0 = mem.span(os.argv[0]);
2239 if (mem.indexOf(u8, argv0, "/") != null) {
2240 // argv[0] is a path (relative or absolute): use realpath(3) directly
2241 var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
2242 const real_path = try os.realpathZ(os.argv[0], &real_path_buf);
2243 if (real_path.len > out_buffer.len)
2244 return error.NameTooLong;
2245 mem.copy(u8, out_buffer, real_path);
2246 return out_buffer[0..real_path.len];
2247 } else if (argv0.len != 0) {
2248 // argv[0] is not empty (and not a path): search it inside PATH
2249 const PATH = std.os.getenv("PATH") orelse "";
2250 var path_it = mem.tokenize(PATH, &[_]u8{path.delimiter});
2251 while (path_it.next()) |a_path| {
2252 var resolved_path_buf: [MAX_PATH_BYTES-1:0]u8 = undefined;
2253 const resolved_path = std.fmt.bufPrint(&resolved_path_buf, "{}/{}\x00", .{
2254 a_path,
2255 os.argv[0],
2256 }) catch "";
2257
2258 var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
2259 if (os.realpathZ(&resolved_path_buf, &real_path_buf) catch null) |real_path| {
2260 // found a file, and hope it is the right file
2261 if (real_path.len > out_buffer.len)
2262 return error.NameTooLong;
2263 mem.copy(u8, out_buffer, real_path);
2264 return out_buffer[0..real_path.len];
2265 }
2266 }
2267 }
2268 }
2269
2270 // sorry, we don't find it
2271 return error.FileNotFound;
2272 },
22352273 .windows => {
22362274 const utf16le_slice = selfExePathW();
22372275 // 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
4949 };
5050 return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
5151 },
52 .linux, .freebsd, .netbsd, .dragonfly => {
52 .linux, .freebsd, .netbsd, .dragonfly, .openbsd => {
5353 const home_dir = os.getenv("HOME") orelse {
5454 // TODO look in /etc/passwd
5555 return error.AppDataDirUnavailable;
lib/std/fs/watch.zig+4-4
......@@ -49,7 +49,7 @@ pub fn Watch(comptime V: type) type {
4949
5050 const OsData = switch (builtin.os.tag) {
5151 // TODO https://github.com/ziglang/zig/issues/3778
52 .macos, .freebsd, .netbsd, .dragonfly => KqOsData,
52 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KqOsData,
5353 .linux => LinuxOsData,
5454 .windows => WindowsOsData,
5555
......@@ -160,7 +160,7 @@ pub fn Watch(comptime V: type) type {
160160 return self;
161161 },
162162
163 .macos, .freebsd, .netbsd, .dragonfly => {
163 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
164164 self.* = Self{
165165 .allocator = allocator,
166166 .channel = channel,
......@@ -178,7 +178,7 @@ pub fn Watch(comptime V: type) type {
178178 /// All addFile calls and removeFile calls must have completed.
179179 pub fn deinit(self: *Self) void {
180180 switch (builtin.os.tag) {
181 .macos, .freebsd, .netbsd, .dragonfly => {
181 .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
182182 // TODO we need to cancel the frames before destroying the lock
183183 self.os_data.table_lock.deinit();
184184 var it = self.os_data.file_table.iterator();
......@@ -229,7 +229,7 @@ pub fn Watch(comptime V: type) type {
229229
230230 pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
231231 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),
233233 .linux => return addFileLinux(self, file_path, value),
234234 .windows => return addFileWindows(self, file_path, value),
235235 else => @compileError("Unsupported OS"),
lib/std/os.zig+5-2
......@@ -33,6 +33,7 @@ pub const darwin = @import("os/darwin.zig");
3333pub const dragonfly = @import("os/dragonfly.zig");
3434pub const freebsd = @import("os/freebsd.zig");
3535pub const netbsd = @import("os/netbsd.zig");
36pub const openbsd = @import("os/openbsd.zig");
3637pub const linux = @import("os/linux.zig");
3738pub const uefi = @import("os/uefi.zig");
3839pub const wasi = @import("os/wasi.zig");
......@@ -47,6 +48,7 @@ test "" {
4748 _ = freebsd;
4849 _ = linux;
4950 _ = netbsd;
51 _ = openbsd;
5052 _ = uefi;
5153 _ = wasi;
5254 _ = windows;
......@@ -66,6 +68,7 @@ else switch (builtin.os.tag) {
6668 .freebsd => freebsd,
6769 .linux => linux,
6870 .netbsd => netbsd,
71 .openbsd => openbsd,
6972 .dragonfly => dragonfly,
7073 .wasi => wasi,
7174 .windows => windows,
......@@ -161,8 +164,8 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
161164 }
162165 return;
163166 }
164 if (builtin.os.tag == .netbsd) {
165 netbsd.arc4random_buf(buffer.ptr, buffer.len);
167 if (builtin.os.tag == .netbsd or builtin.os.tag == .openbsd) {
168 system.arc4random_buf(buffer.ptr, buffer.len);
166169 return;
167170 }
168171 if (builtin.os.tag == .wasi) {
lib/std/os/bits.zig+1
......@@ -17,6 +17,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {
1717 .freebsd => @import("bits/freebsd.zig"),
1818 .linux => @import("bits/linux.zig"),
1919 .netbsd => @import("bits/netbsd.zig"),
20 .openbsd => @import("bits/openbsd.zig"),
2021 .wasi => @import("bits/wasi.zig"),
2122 .windows => @import("bits/windows.zig"),
2223 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" {
618618 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
619619
620620 switch (builtin.os.tag) {
621 .linux, .macos, .ios, .freebsd, .netbsd, .windows => {},
621 .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
622622 else => return,
623623 }
624624 const PackedArray = PackedIntArray(u3, 8);
......@@ -639,7 +639,7 @@ test "PackedIntSlice at end of available memory" {
639639 if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
640640
641641 switch (builtin.os.tag) {
642 .linux, .macos, .ios, .freebsd, .netbsd, .windows => {},
642 .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
643643 else => return,
644644 }
645645 const PackedSlice = PackedIntSlice(u11);
lib/std/process.zig+2-1
......@@ -585,7 +585,7 @@ pub const UserInfo = struct {
585585/// POSIX function which gets a uid from username.
586586pub fn getUserInfo(name: []const u8) !UserInfo {
587587 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),
589589 else => @compileError("Unsupported OS"),
590590 };
591591}
......@@ -712,6 +712,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
712712 .freebsd,
713713 .netbsd,
714714 .dragonfly,
715 .openbsd,
715716 => {
716717 var paths = List.init(allocator);
717718 errdefer {
lib/std/target.zig+3-3
......@@ -266,8 +266,8 @@ pub const Target = struct {
266266 },
267267 .openbsd => return .{
268268 .semver = .{
269 .min = .{ .major = 6, .minor = 6 },
270 .max = .{ .major = 6, .minor = 6 },
269 .min = .{ .major = 6, .minor = 8 },
270 .max = .{ .major = 6, .minor = 8 },
271271 },
272272 },
273273 .dragonfly => return .{
......@@ -1362,6 +1362,7 @@ pub const Target = struct {
13621362 switch (self.os.tag) {
13631363 .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),
13641364 .netbsd => return copy(&result, "/libexec/ld.elf_so"),
1365 .openbsd => return copy(&result, "/libexec/ld.so"),
13651366 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
13661367 .linux => switch (self.cpu.arch) {
13671368 .i386,
......@@ -1471,7 +1472,6 @@ pub const Target = struct {
14711472 .fuchsia,
14721473 .kfreebsd,
14731474 .lv2,
1474 .openbsd,
14751475 .solaris,
14761476 .haiku,
14771477 .minix,
lib/std/zig/cross_target.zig+4
......@@ -449,6 +449,10 @@ pub const CrossTarget = struct {
449449 return self.getOsTag() == .netbsd;
450450 }
451451
452 pub fn isOpenBSD(self: CrossTarget) bool {
453 return self.getOsTag() == .openbsd;
454 }
455
452456 pub fn isUefi(self: CrossTarget) bool {
453457 return self.getOsTag() == .uefi;
454458 }
src/libc_installation.zig+1-1
......@@ -196,7 +196,7 @@ pub const LibCInstallation = struct {
196196 errdefer batch.wait() catch {};
197197 batch.add(&async self.findNativeIncludeDirPosix(args));
198198 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"),
200200 .linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),
201201 else => {},
202202 }
src/link/Elf.zig+20-6
......@@ -1432,7 +1432,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
14321432
14331433 if (link_in_crt) {
14341434 const crt1o: []const u8 = o: {
1435 if (target.os.tag == .netbsd) {
1435 if (target.os.tag == .netbsd or target.os.tag == .openbsd) {
14361436 break :o "crt0.o";
14371437 } else if (target.isAndroid()) {
14381438 if (self.base.options.link_mode == .Dynamic) {
......@@ -1448,7 +1448,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
14481448 };
14491449 try argv.append(try comp.get_libc_crt_file(arena, crt1o));
14501450 if (target_util.libc_needs_crti_crtn(target)) {
1451 try argv.append(try comp.get_libc_crt_file(arena, "crti.o"));
1451 const crti_o = o: {
1452 if (target.os.tag == .openbsd) {
1453 break :o "crtbegin.o";
1454 } else {
1455 break :o "crti.o";
1456 }
1457 };
1458 try argv.append(try comp.get_libc_crt_file(arena, crti_o));
14521459 }
14531460 }
14541461
......@@ -1592,10 +1599,17 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
15921599
15931600 // crt end
15941601 if (link_in_crt) {
1595 if (target.isAndroid()) {
1596 try argv.append(try comp.get_libc_crt_file(arena, "crtend_android.o"));
1597 } else if (target_util.libc_needs_crti_crtn(target)) {
1598 try argv.append(try comp.get_libc_crt_file(arena, "crtn.o"));
1602 if (target.isAndroid() or target_util.libc_needs_crti_crtn(target)) {
1603 const crtn_o = o: {
1604 if (target.os.tag == .openbsd) {
1605 break :o "crtend.o";
1606 } else if (target.isAndroid()) {
1607 break :o "crtend_android.o";
1608 } else {
1609 break :o "crtn.o";
1610 }
1611 };
1612 try argv.append(try comp.get_libc_crt_file(arena, crtn_o));
15991613 }
16001614 }
16011615
src/stage1.zig+3-1
......@@ -25,7 +25,9 @@ comptime {
2525pub const log = stage2.log;
2626pub 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
2931 std.debug.maybeEnableSegfaultHandler();
3032
3133 zig_stage1_os_init();
src/stage1/os.cpp+2-2
......@@ -59,7 +59,7 @@ typedef SSIZE_T ssize_t;
5959
6060#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)
6363#include <link.h>
6464#endif
6565
......@@ -67,7 +67,7 @@ typedef SSIZE_T ssize_t;
6767#include <sys/auxv.h>
6868#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)
7171#include <sys/sysctl.h>
7272#endif
7373
src/stage1/os.hpp+2
......@@ -29,6 +29,8 @@
2929#define ZIG_OS_NETBSD
3030#elif defined(__DragonFly__)
3131#define ZIG_OS_DRAGONFLY
32#elif defined(__OpenBSD__)
33#define ZIG_OS_OPENBSD
3234#else
3335#define ZIG_OS_UNKNOWN
3436#endif
src/target.zig+2-2
......@@ -123,7 +123,7 @@ pub fn cannotDynamicLink(target: std.Target) bool {
123123/// since this is the stable syscall interface.
124124pub fn osRequiresLibC(target: std.Target) bool {
125125 return switch (target.os.tag) {
126 .freebsd, .netbsd, .dragonfly, .macos, .ios, .watchos, .tvos => true,
126 .freebsd, .netbsd, .dragonfly, .openbsd, .macos, .ios, .watchos, .tvos => true,
127127 else => false,
128128 };
129129}
......@@ -143,7 +143,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
143143}
144144
145145pub 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;
147147}
148148
149149/// This function returns whether non-pic code is completely invalid on the given target.