authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-29 16:32:41 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-29 16:32:41 -07:00
log12bcb51d3d96ad8666f1c14a9b607b32c0a7cc9e
tree6a48667d949a0189a6117e3a7d8cf5961884addd
parent68b698eaa0bac158bc20b391a51882f7f1634838
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

add implementation


1 files changed, 370 insertions(+), 0 deletions(-)

sys_darwin.zig+370
......@@ -1 +1,371 @@
11const std = @import("std");
2const builtin = @import("builtin");
3
4comptime {
5 std.debug.assert(builtin.target.os.tag == .macos);
6 std.debug.assert(@bitSizeOf(usize) == 64);
7}
8
9pub const errno = struct {
10 pub const Error = error{
11 Unexpected,
12 EPERM,
13 ENOENT,
14 ESRCH,
15 EINTR,
16 EIO,
17 ENXIO,
18 E2BIG,
19 ENOEXEC,
20 EBADF,
21 ECHILD,
22 EDEADLK,
23 ENOMEM,
24 EACCES,
25 EFAULT,
26 ENOTBLK,
27 EBUSY,
28 EEXIST,
29 EXDEV,
30 ENODEV,
31 ENOTDIR,
32 EISDIR,
33 EINVAL,
34 ENFILE,
35 EMFILE,
36 ENOTTY,
37 ETXTBSY,
38 EFBIG,
39 ENOSPC,
40 ESPIPE,
41 EROFS,
42 EMLINK,
43 EPIPE,
44 EDOM,
45 ERANGE,
46 EAGAIN,
47 EINPROGRESS,
48 EALREADY,
49 ENOTSOCK,
50 EDESTADDRREQ,
51 EMSGSIZE,
52 EPROTOTYPE,
53 ENOPROTOOPT,
54 EPROTONOSUPPORT,
55 ESOCKTNOSUPPORT,
56 ENOTSUP,
57 EPFNOSUPPORT,
58 EAFNOSUPPORT,
59 EADDRINUSE,
60 EADDRNOTAVAIL,
61 ENETDOWN,
62 ENETUNREACH,
63 ENETRESET,
64 ECONNABORTED,
65 ECONNRESET,
66 ENOBUFS,
67 EISCONN,
68 ENOTCONN,
69 ESHUTDOWN,
70 ETOOMANYREFS,
71 ETIMEDOUT,
72 ECONNREFUSED,
73 ELOOP,
74 ENAMETOOLONG,
75 EHOSTDOWN,
76 EHOSTUNREACH,
77 ENOTEMPTY,
78 EPROCLIM,
79 EUSERS,
80 EDQUOT,
81 ESTALE,
82 EREMOTE,
83 EBADRPC,
84 ERPCMISMATCH,
85 EPROGUNAVAIL,
86 EPROGMISMATCH,
87 EPROCUNAVAIL,
88 ENOLCK,
89 ENOSYS,
90 EFTYPE,
91 EAUTH,
92 ENEEDAUTH,
93 EPWROFF,
94 EDEVERR,
95 EOVERFLOW,
96 EBADEXEC,
97 EBADARCH,
98 ESHLIBVERS,
99 EBADMACHO,
100 ECANCELED,
101 EIDRM,
102 ENOMSG,
103 EILSEQ,
104 ENOATTR,
105 EBADMSG,
106 EMULTIHOP,
107 ENODATA,
108 ENOLINK,
109 ENOSR,
110 ENOSTR,
111 EPROTO,
112 ETIME,
113 EOPNOTSUPP,
114 ENOPOLICY,
115 ENOTRECOVERABLE,
116 EOWNERDEAD,
117 EQFULL,
118 ENOTCAPABLE,
119 };
120
121 pub const Enum = enum(c_ushort) {
122 EPERM = 1,
123 ENOENT = 2,
124 ESRCH = 3,
125 EINTR = 4,
126 EIO = 5,
127 ENXIO = 6,
128 E2BIG = 7,
129 ENOEXEC = 8,
130 EBADF = 9,
131 ECHILD = 10,
132 EDEADLK = 11,
133 ENOMEM = 12,
134 EACCES = 13,
135 EFAULT = 14,
136 ENOTBLK = 15,
137 EBUSY = 16,
138 EEXIST = 17,
139 EXDEV = 18,
140 ENODEV = 19,
141 ENOTDIR = 20,
142 EISDIR = 21,
143 EINVAL = 22,
144 ENFILE = 23,
145 EMFILE = 24,
146 ENOTTY = 25,
147 ETXTBSY = 26,
148 EFBIG = 27,
149 ENOSPC = 28,
150 ESPIPE = 29,
151 EROFS = 30,
152 EMLINK = 31,
153 EPIPE = 32,
154 EDOM = 33,
155 ERANGE = 34,
156 EAGAIN = 35,
157 EINPROGRESS = 36,
158 EALREADY = 37,
159 ENOTSOCK = 38,
160 EDESTADDRREQ = 39,
161 EMSGSIZE = 40,
162 EPROTOTYPE = 41,
163 ENOPROTOOPT = 42,
164 EPROTONOSUPPORT = 43,
165 ESOCKTNOSUPPORT = 44,
166 ENOTSUP = 45,
167 EPFNOSUPPORT = 46,
168 EAFNOSUPPORT = 47,
169 EADDRINUSE = 48,
170 EADDRNOTAVAIL = 49,
171 ENETDOWN = 50,
172 ENETUNREACH = 51,
173 ENETRESET = 52,
174 ECONNABORTED = 53,
175 ECONNRESET = 54,
176 ENOBUFS = 55,
177 EISCONN = 56,
178 ENOTCONN = 57,
179 ESHUTDOWN = 58,
180 ETOOMANYREFS = 59,
181 ETIMEDOUT = 60,
182 ECONNREFUSED = 61,
183 ELOOP = 62,
184 ENAMETOOLONG = 63,
185 EHOSTDOWN = 64,
186 EHOSTUNREACH = 65,
187 ENOTEMPTY = 66,
188 EPROCLIM = 67,
189 EUSERS = 68,
190 EDQUOT = 69,
191 ESTALE = 70,
192 EREMOTE = 71,
193 EBADRPC = 72,
194 ERPCMISMATCH = 73,
195 EPROGUNAVAIL = 74,
196 EPROGMISMATCH = 75,
197 EPROCUNAVAIL = 76,
198 ENOLCK = 77,
199 ENOSYS = 78,
200 EFTYPE = 79,
201 EAUTH = 80,
202 ENEEDAUTH = 81,
203 EPWROFF = 82,
204 EDEVERR = 83,
205 EOVERFLOW = 84,
206 EBADEXEC = 85,
207 EBADARCH = 86,
208 ESHLIBVERS = 87,
209 EBADMACHO = 88,
210 ECANCELED = 89,
211 EIDRM = 90,
212 ENOMSG = 91,
213 EILSEQ = 92,
214 ENOATTR = 93,
215 EBADMSG = 94,
216 EMULTIHOP = 95,
217 ENODATA = 96,
218 ENOLINK = 97,
219 ENOSR = 98,
220 ENOSTR = 99,
221 EPROTO = 100,
222 ETIME = 101,
223 // 102 is only defined in the kernel
224 ENOPOLICY = 103,
225 ENOTRECOVERABLE = 104,
226 EOWNERDEAD = 105,
227 EQFULL = 106,
228 ENOTCAPABLE = 107,
229
230 pub const EWOULDBLOCK: Enum = .EAGAIN;
231 pub const EOPNOTSUPP: Enum = .ENOTSUP;
232 };
233
234 comptime {
235 // assert Enum is sequential
236 var value: c_ushort = 0; // SUCCESS
237 for (std.enums.values(Enum)) |val| {
238 std.debug.assert(@intFromEnum(val) > value);
239 value = @intFromEnum(val);
240 }
241 }
242 comptime {
243 // sanity test
244 std.debug.assert(@intFromEnum(Enum.EPERM) == 1);
245 }
246 const list = blk: {
247 const values = std.enums.values(Enum);
248 const len = @intFromEnum(values[values.len - 1]) + 1;
249 var errors: [len]Error = @splat(error.Unexpected);
250 for (values) |f| errors[@intFromEnum(f)] = @field(Error, @tagName(f));
251 const final = errors;
252 break :blk final;
253 };
254 pub fn fromInt(code: c_int) Error {
255 @setRuntimeSafety(false);
256 if (code >= list.len) return error.Unexpected;
257 if (code <= 0) return error.Unexpected;
258 return list[@intCast(code)];
259 }
260 pub fn fromLibC() c_int {
261 return libc.__error().*;
262 }
263};
264
265pub const libc = struct {
266 pub extern fn __error() *c_int;
267 pub extern fn openat(fd: c_int, file: [*:0]const u8, oflag: c_int, ...) c_int;
268 pub extern fn fstat(fd: c_int, buf: *struct_stat) c_int;
269 pub extern fn close(fildes: c_int) c_int;
270 pub extern fn read(fd: c_int, buf: [*]u8, count: usize) isize;
271 pub extern fn clock_gettime(clock_id: clockid_t, tp: *struct_timespec) c_int;
272};
273
274pub const natural_t = c_uint;
275pub const blkcnt_t = i64;
276pub const blksize_t = i32;
277pub const dev_t = i32;
278pub const fsblkcnt_t = c_uint;
279pub const fsfilcnt_t = c_uint;
280pub const gid_t = u32;
281pub const id_t = u32;
282pub const ino_t = u64;
283pub const mach_port_name_t = natural_t;
284pub const mach_port_t = mach_port_name_t;
285pub const mode_t = u16;
286pub const off_t = i64;
287pub const pid_t = i32;
288pub const sigset_t = u32;
289pub const suseconds_t = i32;
290pub const uid_t = u32;
291pub const useconds_t = u32;
292pub const nlink_t = u16;
293pub const clockid_t = c_int;
294
295pub const time_t = c_ulong;
296
297pub const struct_timespec = extern struct { sec: time_t, nsec: c_long };
298pub const struct_stat = extern struct { dev: dev_t, mode: mode_t, nlink: nlink_t, ino: ino_t, uid: uid_t, gid: gid_t, rdev: dev_t, atimespec: struct_timespec, mtimespec: struct_timespec, ctimespec: struct_timespec, birthtimespec: struct_timespec, size: off_t, blocks: blkcnt_t, blksize: blksize_t, flags: u32, gen: u32, lspare: i32, qspare: [2]i64 };
299pub const struct_iovec = extern struct { base: [*]u8, len: usize };
300
301pub const O = struct {
302 pub const RDONLY = 0x0000;
303 pub const WRONLY = 0x0001;
304 pub const RDWR = 0x0002;
305 pub const ACCMODE = 0x0003;
306 pub const NONBLOCK = 0x00000004;
307 pub const APPEND = 0x00000008;
308 pub const SYNC = 0x0080;
309 pub const SHLOCK = 0x00000010;
310 pub const EXLOCK = 0x00000020;
311 pub const ASYNC = 0x00000040;
312 pub const FSYNC = SYNC;
313 pub const NOFOLLOW = 0x00000100;
314 pub const CREAT = 0x00000200;
315 pub const TRUNC = 0x00000400;
316 pub const EXCL = 0x00000800;
317 pub const RESOLVE_BENEATH = 0x00001000;
318 pub const UNIQUE = 0x00002000;
319 pub const EVTONLY = 0x00008000;
320 pub const NOCTTY = 0x00020000;
321 pub const DIRECTORY = 0x00100000;
322 pub const SYMLINK = 0x00200000;
323 pub const DSYNC = 0x00400000;
324 pub const CLOEXEC = 0x01000000;
325 pub const NOFOLLOW_ANY = 0x20000000;
326 pub const EXEC = 0x40000000;
327 pub const SEARCH = (EXEC | DIRECTORY);
328};
329
330pub const CLOCK = struct {
331 pub const REALTIME = 0;
332 pub const MONOTONIC = 6;
333 pub const MONOTONIC_RAW = 4;
334 pub const MONOTONIC_RAW_APPROX = 5;
335 pub const UPTIME_RAW = 8;
336 pub const UPTIME_RAW_APPROX = 9;
337 pub const PROCESS_CPUTIME_ID = 12;
338 pub const THREAD_CPUTIME_ID = 16;
339};
340
341pub fn openat(fd: c_int, file: [*:0]const u8, oflag: c_int) errno.Error!c_int {
342 const rc = libc.openat(fd, file, oflag);
343 if (rc == -1) return errno.fromInt(errno.fromLibC());
344 std.debug.assert(rc >= 0);
345 return rc;
346}
347pub fn fstat(fd: c_int) errno.Error!struct_stat {
348 var buf: struct_stat = undefined;
349 const rc = libc.fstat(fd, &buf);
350 if (rc == -1) return errno.fromInt(errno.fromLibC());
351 std.debug.assert(rc == 0);
352 return buf;
353}
354pub fn close(fd: c_int) errno.Error!void {
355 const rc = libc.close(fd);
356 if (rc == -1) return errno.fromInt(errno.fromLibC());
357 std.debug.assert(rc == 0);
358}
359pub fn read(fd: c_int, buf: []u8) errno.Error!usize {
360 const rc = libc.read(fd, buf.ptr, buf.len);
361 if (rc == -1) return errno.fromInt(errno.fromLibC());
362 std.debug.assert(rc >= 0);
363 return @intCast(rc);
364}
365pub fn clock_gettime(clock_id: clockid_t) !struct_timespec {
366 var tp: struct_timespec = undefined;
367 const rc = libc.clock_gettime(clock_id, &tp);
368 if (rc == -1) return errno.fromInt(errno.fromLibC());
369 std.debug.assert(rc == 0);
370 return tp;
371}