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};