master
1const builtin = @import("builtin");
2const std = @import("../std.zig");
3const assert = std.debug.assert;
4const SO = std.c.SO;
5const fd_t = std.c.fd_t;
6const gid_t = std.c.gid_t;
7const ino_t = std.c.ino_t;
8const mode_t = std.c.mode_t;
9const off_t = std.c.off_t;
10const pid_t = std.c.pid_t;
11const pthread_t = std.c.pthread_t;
12const sockaddr = std.c.sockaddr;
13const socklen_t = std.c.socklen_t;
14const timespec = std.c.timespec;
15const uid_t = std.c.uid_t;
16const IFNAMESIZE = std.c.IFNAMESIZE;
17
18comptime {
19 assert(builtin.os.tag == .illumos); // Prevent access of std.c symbols on wrong OS.
20}
21
22pub extern "c" fn pthread_setname_np(thread: pthread_t, name: [*:0]const u8, arg: ?*anyopaque) c_int;
23pub extern "c" fn sysconf(sc: c_int) i64;
24
25pub const major_t = u32;
26pub const minor_t = u32;
27pub const id_t = i32;
28pub const taskid_t = id_t;
29pub const projid_t = id_t;
30pub const poolid_t = id_t;
31pub const zoneid_t = id_t;
32pub const ctid_t = id_t;
33
34pub const GETCONTEXT = 0;
35pub const SETCONTEXT = 1;
36pub const GETUSTACK = 2;
37pub const SETUSTACK = 3;
38
39pub const POSIX_FADV = struct {
40 pub const NORMAL = 0;
41 pub const RANDOM = 1;
42 pub const SEQUENTIAL = 2;
43 pub const WILLNEED = 3;
44 pub const DONTNEED = 4;
45 pub const NOREUSE = 5;
46};
47
48pub const priority = enum(c_int) {
49 PROCESS = 0,
50 PGRP = 1,
51 USER = 2,
52 GROUP = 3,
53 SESSION = 4,
54 LWP = 5,
55 TASK = 6,
56 PROJECT = 7,
57 ZONE = 8,
58 CONTRACT = 9,
59};
60
61/// Extensions to the ELF auxiliary vector.
62pub const AT_SUN = struct {
63 /// effective user id
64 pub const UID = 2000;
65 /// real user id
66 pub const RUID = 2001;
67 /// effective group id
68 pub const GID = 2002;
69 /// real group id
70 pub const RGID = 2003;
71 /// dynamic linker's ELF header
72 pub const LDELF = 2004;
73 /// dynamic linker's section headers
74 pub const LDSHDR = 2005;
75 /// name of dynamic linker
76 pub const LDNAME = 2006;
77 /// large pagesize
78 pub const LPAGESZ = 2007;
79 /// platform name
80 pub const PLATFORM = 2008;
81 /// hints about hardware capabilities.
82 pub const HWCAP = 2009;
83 pub const HWCAP2 = 2023;
84 /// flush icache?
85 pub const IFLUSH = 2010;
86 /// cpu name
87 pub const CPU = 2011;
88 /// exec() path name in the auxv, null terminated.
89 pub const EXECNAME = 2014;
90 /// mmu module name
91 pub const MMU = 2015;
92 /// dynamic linkers data segment
93 pub const LDDATA = 2016;
94 /// AF_SUN_ flags passed from the kernel
95 pub const AUXFLAGS = 2017;
96 /// name of the emulation binary for the linker
97 pub const EMULATOR = 2018;
98 /// name of the brand library for the linker
99 pub const BRANDNAME = 2019;
100 /// vectors for brand modules.
101 pub const BRAND_AUX1 = 2020;
102 pub const BRAND_AUX2 = 2021;
103 pub const BRAND_AUX3 = 2022;
104 pub const BRAND_AUX4 = 2025;
105 pub const BRAND_NROOT = 2024;
106 /// vector for comm page.
107 pub const COMMPAGE = 2026;
108 /// information about the x86 FPU.
109 pub const FPTYPE = 2027;
110 pub const FPSIZE = 2028;
111};
112
113/// ELF auxiliary vector flags.
114pub const AF_SUN = struct {
115 /// tell ld.so.1 to run "secure" and ignore the environment.
116 pub const SETUGID = 0x00000001;
117 /// hardware capabilities can be verified against AT_SUN_HWCAP
118 pub const HWCAPVERIFY = 0x00000002;
119 pub const NOPLM = 0x00000004;
120};
121
122pub const procfs = struct {
123 pub const misc_header = extern struct {
124 size: u32,
125 type: enum(u32) {
126 Pathname,
127 Socketname,
128 Peersockname,
129 SockoptsBoolOpts,
130 SockoptLinger,
131 SockoptSndbuf,
132 SockoptRcvbuf,
133 SockoptIpNexthop,
134 SockoptIpv6Nexthop,
135 SockoptType,
136 SockoptTcpCongestion,
137 SockfiltersPriv = 14,
138 },
139 };
140
141 pub const fdinfo = extern struct {
142 fd: fd_t,
143 mode: mode_t,
144 ino: ino_t,
145 size: off_t,
146 offset: off_t,
147 uid: uid_t,
148 gid: gid_t,
149 dev_major: major_t,
150 dev_minor: minor_t,
151 special_major: major_t,
152 special_minor: minor_t,
153 fileflags: i32,
154 fdflags: i32,
155 locktype: i16,
156 lockpid: pid_t,
157 locksysid: i32,
158 peerpid: pid_t,
159 __filler: [25]c_int,
160 peername: [15:0]u8,
161 misc: [1]u8,
162 };
163};
164
165pub const SFD = struct {
166 pub const CLOEXEC = 0o2000000;
167 pub const NONBLOCK = 0o4000;
168};
169
170pub const signalfd_siginfo = extern struct {
171 signo: u32,
172 errno: i32,
173 code: i32,
174 pid: u32,
175 uid: uid_t,
176 fd: i32,
177 tid: u32, // unused
178 band: u32,
179 overrun: u32, // unused
180 trapno: u32,
181 status: i32,
182 int: i32, // unused
183 ptr: u64, // unused
184 utime: u64,
185 stime: u64,
186 addr: u64,
187 __pad: [48]u8,
188};
189
190pub const PORT_SOURCE = struct {
191 pub const AIO = 1;
192 pub const TIMER = 2;
193 pub const USER = 3;
194 pub const FD = 4;
195 pub const ALERT = 5;
196 pub const MQ = 6;
197 pub const FILE = 7;
198};
199
200pub const PORT_ALERT = struct {
201 pub const SET = 0x01;
202 pub const UPDATE = 0x02;
203};
204
205/// User watchable file events.
206pub const FILE_EVENT = struct {
207 pub const ACCESS = 0x00000001;
208 pub const MODIFIED = 0x00000002;
209 pub const ATTRIB = 0x00000004;
210 pub const DELETE = 0x00000010;
211 pub const RENAME_TO = 0x00000020;
212 pub const RENAME_FROM = 0x00000040;
213 pub const TRUNC = 0x00100000;
214 pub const NOFOLLOW = 0x10000000;
215 /// The filesystem holding the watched file was unmounted.
216 pub const UNMOUNTED = 0x20000000;
217 /// Some other file/filesystem got mounted over the watched file/directory.
218 pub const MOUNTEDOVER = 0x40000000;
219
220 pub fn isException(event: u32) bool {
221 return event & (UNMOUNTED | DELETE | RENAME_TO | RENAME_FROM | MOUNTEDOVER) > 0;
222 }
223};
224
225pub const port_notify = extern struct {
226 /// Bind request(s) to port.
227 port: u32,
228 /// User defined variable.
229 user: ?*void,
230};
231
232pub const file_obj = extern struct {
233 /// Access time.
234 atim: timespec,
235 /// Modification time
236 mtim: timespec,
237 /// Change time
238 ctim: timespec,
239 __pad: [3]usize,
240 name: [*:0]u8,
241};
242
243// struct ifreq is marked obsolete, with struct lifreq preferred for interface requests.
244// Here we alias lifreq to ifreq to avoid chainging existing code in os and x.os.IPv6.
245pub const SIOCGLIFINDEX = IOWR('i', 133, lifreq);
246
247pub const lif_nd_req = extern struct {
248 addr: sockaddr.storage,
249 state_create: u8,
250 state_same_lla: u8,
251 state_diff_lla: u8,
252 hdw_len: i32,
253 flags: i32,
254 __pad: i32,
255 hdw_addr: [64]u8,
256};
257
258pub const lif_ifinfo_req = extern struct {
259 maxhops: u8,
260 reachtime: u32,
261 reachretrans: u32,
262 maxmtu: u32,
263};
264
265/// IP interface request. See if_tcp(7p) for more info.
266pub const lifreq = extern struct {
267 // Not actually in a union, but the stdlib expects one for ifreq
268 ifrn: extern union {
269 /// Interface name, e.g. "lo0", "en0".
270 name: [IFNAMESIZE]u8,
271 },
272 ru1: extern union {
273 /// For subnet/token etc.
274 addrlen: i32,
275 /// Driver's PPA (physical point of attachment).
276 ppa: u32,
277 },
278 /// One of the IFT types, e.g. IFT_ETHER.
279 type: u32,
280 ifru: extern union {
281 /// Address.
282 addr: sockaddr.storage,
283 /// Other end of a peer-to-peer link.
284 dstaddr: sockaddr.storage,
285 /// Broadcast address.
286 broadaddr: sockaddr.storage,
287 /// Address token.
288 token: sockaddr.storage,
289 /// Subnet prefix.
290 subnet: sockaddr.storage,
291 /// Interface index.
292 ivalue: i32,
293 /// Flags for SIOC?LIFFLAGS.
294 flags: u64,
295 /// Hop count metric
296 metric: i32,
297 /// Maximum transmission unit
298 mtu: u32,
299 // Technically [2]i32
300 muxid: packed struct { ip: i32, arp: i32 },
301 /// Neighbor reachability determination entries
302 nd_req: lif_nd_req,
303 /// Link info
304 ifinfo_req: lif_ifinfo_req,
305 /// Name of the multipath interface group
306 groupname: [IFNAMESIZE]u8,
307 binding: [IFNAMESIZE]u8,
308 /// Zone id associated with this interface.
309 zoneid: zoneid_t,
310 /// Duplicate address detection state. Either in progress or completed.
311 dadstate: u32,
312 },
313};
314
315const IoCtlCommand = enum(u32) {
316 none = 0x20000000, // no parameters
317 write = 0x40000000, // copy out parameters
318 read = 0x80000000, // copy in parameters
319 read_write = 0xc0000000,
320};
321
322fn ioImpl(cmd: IoCtlCommand, io_type: u8, nr: u8, comptime IOT: type) i32 {
323 const size = @as(u32, @intCast(@as(u8, @truncate(@sizeOf(IOT))))) << 16;
324 const t = @as(u32, @intCast(io_type)) << 8;
325 return @as(i32, @bitCast(@intFromEnum(cmd) | size | t | nr));
326}
327
328pub fn IO(io_type: u8, nr: u8) i32 {
329 return ioImpl(.none, io_type, nr, void);
330}
331
332pub fn IOR(io_type: u8, nr: u8, comptime IOT: type) i32 {
333 return ioImpl(.write, io_type, nr, IOT);
334}
335
336pub fn IOW(io_type: u8, nr: u8, comptime IOT: type) i32 {
337 return ioImpl(.read, io_type, nr, IOT);
338}
339
340pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 {
341 return ioImpl(.read_write, io_type, nr, IOT);
342}
343
344// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/netinet/in.h#L1141
345// (old OpenSolaris is very similar, it's just missing a few more-modern ones, and probably modern Solaris has those)
346pub const IP = struct {
347 pub const OPTIONS = 1;
348 pub const HDRINCL = 2;
349 pub const TOS = 3;
350 pub const TTL = 4;
351 pub const RECVOPTS = 0x5;
352 pub const RECVRETOPTS = 0x6;
353 pub const RECVDSTADDR = 0x7;
354 pub const RETOPTS = 0x8;
355 pub const RECVIF = 0x9;
356 pub const RECVSLLA = 0xa;
357 pub const RECVTTL = 0xb;
358 pub const RECVTOS = 0xc;
359 pub const MULTICAST_IF = 0x10;
360 pub const MULTICAST_TTL = 0x11;
361 pub const MULTICAST_LOOP = 0x12;
362 pub const ADD_MEMBERSHIP = 0x13;
363 pub const DROP_MEMBERSHIP = 0x14;
364 pub const BLOCK_SOURCE = 0x15;
365 pub const UNBLOCK_SOURCE = 0x16;
366 pub const ADD_SOURCE_MEMBERSHIP = 0x17;
367 pub const DROP_SOURCE_MEMBERSHIP = 0x18;
368 pub const NEXTHOP = 0x19;
369 pub const PKTINFO = 0x1a;
370 pub const RECVPKTINFO = 0x1a;
371 pub const DONTFRAG = 0x1b;
372 pub const MINTTL = 0x1c;
373 pub const SEC_OPT = 0x22;
374 pub const BOUND_IF = 0x41;
375 pub const UNSPEC_SRC = 0x42;
376 pub const BROADCAST_TTL = 0x43;
377 pub const DHCPINIT_IF = 0x45;
378 pub const REUSEADDR = 0x104;
379 pub const DONTROUTE = 0x105;
380 pub const BROADCAST = 0x106;
381 // Same namespace, but these are arguments rather than option names
382 pub const DEFAULT_MULTICAST_TTL = 1;
383 pub const DEFAULT_MULTICAST_LOOP = 1;
384};
385
386// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/netinet/in.h#L1192
387// (old OpenSolaris is very similar, it's just missing a few more-modern ones, and probably modern Solaris has those)
388pub const IPV6 = struct {
389 pub const UNICAST_HOPS = 0x5;
390 pub const MULTICAST_IF = 0x6;
391 pub const MULTICAST_HOPS = 0x7;
392 pub const MULTICAST_LOOP = 0x8;
393 pub const JOIN_GROUP = 0x9;
394 pub const LEAVE_GROUP = 0xa;
395 pub const ADD_MEMBERSHIP = 0x9;
396 pub const DROP_MEMBERSHIP = 0xa;
397 pub const PKTINFO = 0xb;
398 pub const HOPLIMIT = 0xc;
399 pub const NEXTHOP = 0xd;
400 pub const HOPOPTS = 0xe;
401 pub const DSTOPTS = 0xf;
402 pub const RTHDR = 0x10;
403 pub const RTHDRDSTOPTS = 0x11;
404 pub const RECVPKTINFO = 0x12;
405 pub const RECVHOPLIMIT = 0x13;
406 pub const RECVHOPOPTS = 0x14;
407 pub const OLD_RECVDSTOPTS = 0x15;
408 pub const RECVRTHDR = 0x16;
409 pub const RECVRTHDRDSTOPTS = 0x17;
410 pub const CHECKSUM = 0x18;
411 pub const RECVTCLASS = 0x19;
412 pub const USE_MIN_MTU = 0x20;
413 pub const DONTFRAG = 0x21;
414 pub const SEC_OPT = 0x22;
415 pub const SRC_PREFERENCES = 0x23;
416 pub const RECVPATHMTU = 0x24;
417 pub const PATHMTU = 0x25;
418 pub const TCLASS = 0x26;
419 pub const V6ONLY = 0x27;
420 pub const RECVDSTOPTS = 0x28;
421 pub const MINHOPCOUNT = 0x2f;
422 pub const BOUND_IF = 0x41;
423 pub const UNSPEC_SRC = 0x42;
424 // Same namespace, but these are arguments rather than option names
425 pub const RTHDR_TYPE_0 = 0;
426 pub const PREFER_SRC_HOME = 0x01;
427 pub const PREFER_SRC_COA = 0x02;
428 pub const PREFER_SRC_PUBLIC = 0x04;
429 pub const PREFER_SRC_TMP = 0x08;
430 pub const PREFER_SRC_NONCGA = 0x10;
431 pub const PREFER_SRC_CGA = 0x20;
432 pub const PREFER_SRC_MIPMASK = PREFER_SRC_HOME | PREFER_SRC_COA;
433 pub const PREFER_SRC_MIPDEFAULT = PREFER_SRC_HOME;
434 pub const PREFER_SRC_TMPMASK = PREFER_SRC_PUBLIC | PREFER_SRC_TMP;
435 pub const PREFER_SRC_TMPDEFAULT = PREFER_SRC_PUBLIC;
436 pub const PREFER_SRC_CGAMASK = PREFER_SRC_NONCGA | PREFER_SRC_CGA;
437 pub const PREFER_SRC_CGADEFAULT = PREFER_SRC_NONCGA;
438 pub const PREFER_SRC_MASK = PREFER_SRC_MIPMASK | PREFER_SRC_TMPMASK | PREFER_SRC_CGAMASK;
439 pub const PREFER_SRC_DEFAULT = PREFER_SRC_MIPDEFAULT | PREFER_SRC_TMPDEFAULT | PREFER_SRC_CGADEFAULT;
440};
441
442// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/netinet/ip.h#L64
443pub const IPTOS = struct {
444 pub const LOWDELAY = 0x10;
445 pub const THROUGHPUT = 0x08;
446 pub const RELIABILITY = 0x04;
447 pub const ECT = 0x02;
448 pub const CE = 0x01;
449 pub const PREC_NETCONTROL = 0xe0;
450 pub const PREC_INTERNETCONTROL = 0xc0;
451 pub const PREC_CRITIC_ECP = 0xa0;
452 pub const PREC_FLASHOVERRIDE = 0x80;
453 pub const PREC_FLASH = 0x60;
454 pub const PREC_IMMEDIATE = 0x40;
455 pub const PREC_PRIORITY = 0x20;
456 pub const PREC_ROUTINE = 0x00;
457};