authorgravatar for dev@sgregoratto.meStephen Gregoratto <dev@sgregoratto.me> 2021-08-31 22:21:23+10:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-24 14:06:16-04:00
log87fd502fb68f8f488e6eba6b1f7d70902d6bfe5a
treee6fa3a1c4b83deb7f03fa191456ef2c4fac5cf3b
parenta032fd01e88be2c6e8d0cfb0ccd3d9859c9dffdc

Initial bringup of the Solaris/Illumos port


20 files changed, 2148 insertions(+), 55 deletions(-)

lib/std/Thread.zig+13-2
......@@ -41,6 +41,7 @@ pub const max_name_len = switch (target.os.tag) {
4141 .netbsd => 31,
4242 .freebsd => 15,
4343 .openbsd => 31,
44 .solaris => 31,
4445 else => 0,
4546};
4647
......@@ -112,7 +113,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
112113 else => |e| return os.unexpectedErrno(e),
113114 }
114115 },
115 .netbsd => if (use_pthreads) {
116 .netbsd, .solaris => if (use_pthreads) {
116117 const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null);
117118 switch (err) {
118119 .SUCCESS => return,
......@@ -202,7 +203,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
202203 else => |e| return os.unexpectedErrno(e),
203204 }
204205 },
205 .netbsd => if (use_pthreads) {
206 .netbsd, .solaris => if (use_pthreads) {
206207 const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1);
207208 switch (err) {
208209 .SUCCESS => return std.mem.sliceTo(buffer, 0),
......@@ -565,6 +566,16 @@ const PosixThreadImpl = struct {
565566 };
566567 return @intCast(usize, count);
567568 },
569 .solaris => {
570 // The "proper" way to get the cpu count would be to query
571 // /dev/kstat via ioctls, and traverse a linked list for each
572 // cpu.
573 const rc = c.sysconf(os._SC.NPROCESSORS_ONLN);
574 return switch (os.errno(rc)) {
575 .SUCCESS => @intCast(usize, rc),
576 else => |err| os.unexpectedErrno(err),
577 };
578 },
568579 .haiku => {
569580 var count: u32 = undefined;
570581 var system_info: os.system_info = undefined;
lib/std/c.zig+27
......@@ -252,6 +252,33 @@ pub extern "c" fn kevent(
252252 timeout: ?*const c.timespec,
253253) c_int;
254254
255pub extern "c" fn port_create() c.port_t;
256pub extern "c" fn port_associate(
257 port: c.port_t,
258 source: u32,
259 object: usize,
260 events: u32,
261 user_var: ?*c_void,
262) c_int;
263pub extern "c" fn port_dissociate(port: c.port_t, source: u32, object: usize) c_int;
264pub extern "c" fn port_send(port: c.port_t, events: u32, user_var: ?*c_void) c_int;
265pub extern "c" fn port_sendn(
266 ports: [*]c.port_t,
267 errors: []u32,
268 num_ports: u32,
269 events: u32,
270 user_var: ?*c_void,
271) c_int;
272pub extern "c" fn port_get(port: c.port_t, event: *c.port_event, timeout: ?*c.timespec) c_int;
273pub extern "c" fn port_getn(
274 port: c.port_t,
275 event_list: []c.port_event,
276 max_events: u32,
277 events_retrieved: *u32,
278 timeout: ?*c.timespec,
279) c_int;
280pub extern "c" fn port_alert(port: c.port_t, flags: u32, events: u32, user_var: ?*c_void) c_int;
281
255282pub extern "c" fn getaddrinfo(
256283 noalias node: ?[*:0]const u8,
257284 noalias service: ?[*:0]const u8,
lib/std/c/solaris.zig+1909-11
......@@ -1,15 +1,1913 @@
1const std = @import("../std.zig");
2const builtin = @import("builtin");
3const maxInt = std.math.maxInt;
4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
6const timezone = std.c.timezone;
7
8extern "c" fn ___errno() *c_int;
9pub const _errno = ___errno;
10
11pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
12pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
13
14pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
15pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
16pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
17pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
18pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int;
19pub extern "c" fn sysconf(sc: c_int) i64;
20pub extern "c" fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) c_int;
21pub extern "c" fn madvise(address: [*]u8, len: usize, advise: u32) c_int;
22
123pub const pthread_mutex_t = extern struct {
2 __pthread_mutex_flag1: u16 = 0,
3 __pthread_mutex_flag2: u8 = 0,
4 __pthread_mutex_ceiling: u8 = 0,
5 __pthread_mutex_type: u16 = 0,
6 __pthread_mutex_magic: u16 = 0x4d58,
7 __pthread_mutex_lock: u64 = 0,
8 __pthread_mutex_data: u64 = 0,
24 flag1: u16 = 0,
25 flag2: u8 = 0,
26 ceiling: u8 = 0,
27 @"type": u16 = 0,
28 magic: u16 = 0x4d58,
29 lock: u64 = 0,
30 data: u64 = 0,
931};
1032pub const pthread_cond_t = extern struct {
11 __pthread_cond_flag: u32 = 0,
12 __pthread_cond_type: u16 = 0,
13 __pthread_cond_magic: u16 = 0x4356,
14 __pthread_cond_data: u64 = 0,
33 flag: [4]u8 = [_]u8{0} ** 4,
34 @"type": u16 = 0,
35 magic: u16 = 0x4356,
36 data: u64 = 0,
1537};
38pub const pthread_rwlock_t = extern struct {
39 readers: i32 = 0,
40 @"type": u16 = 0,
41 magic: u16 = 0x5257,
42 mutex: pthread_mutex_t = .{},
43 readercv: pthread_cond_t = .{},
44 writercv: pthread_cond_t = .{},
45};
46pub const pthread_attr_t = extern struct {
47 mutexattr: ?*c_void = null,
48};
49pub const pthread_key_t = c_int;
50
51pub const sem_t = extern struct {
52 count: u32 = 0,
53 @"type": u16 = 0,
54 magic: u16 = 0x534d,
55 __pad1: [3]u64 = [_]u64{0} ** 3,
56 __pad2: [2]u64 = [_]u64{0} ** 2,
57};
58
59pub extern "c" fn pthread_setname_np(thread: std.c.pthread_t, name: [*:0]const u8, arg: ?*c_void) E;
60pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;
61
62pub const blkcnt_t = i64;
63pub const blksize_t = i32;
64pub const clock_t = i64;
65pub const dev_t = i32;
66pub const fd_t = c_int;
67pub const gid_t = u32;
68pub const ino_t = u64;
69pub const mode_t = u32;
70pub const nlink_t = u32;
71pub const off_t = i64;
72pub const pid_t = i32;
73pub const socklen_t = u32;
74pub const time_t = i64;
75pub const suseconds_t = i64;
76pub const uid_t = u32;
77pub const major_t = u32;
78pub const minor_t = u32;
79pub const port_t = c_int;
80pub const nfds_t = usize;
81pub const id_t = i32;
82pub const taskid_t = id_t;
83pub const projid_t = id_t;
84pub const poolid_t = id_t;
85pub const zoneid_t = id_t;
86pub const ctid_t = id_t;
87
88pub const dl_phdr_info = extern struct {
89 dlpi_addr: std.elf.Addr,
90 dlpi_name: ?[*:0]const u8,
91 dlpi_phdr: [*]std.elf.Phdr,
92 dlpi_phnum: std.elf.Half,
93 /// Incremented when a new object is mapped into the process.
94 dlpi_adds: u64,
95 /// Incremented when an object is unmapped from the process.
96 dlpi_subs: u64,
97};
98
99pub const RTLD = struct {
100 pub const LAZY = 0x00001;
101 pub const NOW = 0x00002;
102 pub const NOLOAD = 0x00004;
103 pub const GLOBAL = 0x00100;
104 pub const LOCAL = 0x00000;
105 pub const PARENT = 0x00200;
106 pub const GROUP = 0x00400;
107 pub const WORLD = 0x00800;
108 pub const NODELETE = 0x01000;
109 pub const FIRST = 0x02000;
110 pub const CONFGEN = 0x10000;
111
112 pub const NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
113 pub const DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
114 pub const SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
115 pub const PROBE = @intToPtr(*c_void, @bitCast(usize, @as(isize, -4)));
116};
117
118pub const Flock = extern struct {
119 l_type: c_short,
120 l_whence: c_short,
121 l_start: off_t,
122 // len == 0 means until end of file.
123 l_len: off_t,
124 l_sysid: c_int,
125 l_pid: pid_t,
126 __pad: [4]c_long,
127};
128
129pub const utsname = extern struct {
130 sysname: [256:0]u8,
131 nodename: [256:0]u8,
132 release: [256:0]u8,
133 version: [256:0]u8,
134 machine: [256:0]u8,
135 domainname: [256:0]u8,
136};
137
138pub const addrinfo = extern struct {
139 flags: i32,
140 family: i32,
141 socktype: i32,
142 protocol: i32,
143 addrlen: socklen_t,
144 canonname: ?[*:0]u8,
145 addr: ?*sockaddr,
146 next: ?*addrinfo,
147};
148
149pub const EAI = enum(c_int) {
150 /// address family for hostname not supported
151 ADDRFAMILY = 1,
152 /// name could not be resolved at this time
153 AGAIN = 2,
154 /// flags parameter had an invalid value
155 BADFLAGS = 3,
156 /// non-recoverable failure in name resolution
157 FAIL = 4,
158 /// address family not recognized
159 FAMILY = 5,
160 /// memory allocation failure
161 MEMORY = 6,
162 /// no address associated with hostname
163 NODATA = 7,
164 /// name does not resolve
165 NONAME = 8,
166 /// service not recognized for socket type
167 SERVICE = 9,
168 /// intended socket type was not recognized
169 SOCKTYPE = 10,
170 /// system error returned in errno
171 SYSTEM = 11,
172 /// argument buffer overflow
173 OVERFLOW = 12,
174 /// resolved protocol is unknown
175 PROTOCOL = 13,
176
177 _,
178};
179
180pub const EAI_MAX = 14;
181
182pub const msghdr = extern struct {
183 /// optional address
184 msg_name: ?*sockaddr,
185 /// size of address
186 msg_namelen: socklen_t,
187 /// scatter/gather array
188 msg_iov: [*]iovec,
189 /// # elements in msg_iov
190 msg_iovlen: i32,
191 /// ancillary data
192 msg_control: ?*c_void,
193 /// ancillary data buffer len
194 msg_controllen: socklen_t,
195 /// flags on received message
196 msg_flags: i32,
197};
198
199pub const msghdr_const = extern struct {
200 /// optional address
201 msg_name: ?*const sockaddr,
202 /// size of address
203 msg_namelen: socklen_t,
204 /// scatter/gather array
205 msg_iov: [*]iovec_const,
206 /// # elements in msg_iov
207 msg_iovlen: i32,
208 /// ancillary data
209 msg_control: ?*c_void,
210 /// ancillary data buffer len
211 msg_controllen: socklen_t,
212 /// flags on received message
213 msg_flags: i32,
214};
215
216pub const cmsghdr = extern struct {
217 cmsg_len: socklen_t,
218 cmsg_level: i32,
219 cmsg_type: i32,
220};
221
222/// The stat structure used by libc.
223pub const Stat = extern struct {
224 dev: dev_t,
225 ino: ino_t,
226 mode: mode_t,
227 nlink: nlink_t,
228 uid: uid_t,
229 gid: gid_t,
230 rdev: dev_t,
231 size: off_t,
232 atim: timespec,
233 mtim: timespec,
234 ctim: timespec,
235 blksize: blksize_t,
236 blocks: blkcnt_t,
237 fstype: [16]u8,
238
239 pub fn atime(self: @This()) timespec {
240 return self.atim;
241 }
242
243 pub fn mtime(self: @This()) timespec {
244 return self.mtim;
245 }
246
247 pub fn ctime(self: @This()) timespec {
248 return self.ctim;
249 }
250};
251
252pub const timespec = extern struct {
253 tv_sec: i64,
254 tv_nsec: isize,
255};
256
257pub const timeval = extern struct {
258 /// seconds
259 tv_sec: time_t,
260 /// microseconds
261 tv_usec: suseconds_t,
262};
263
264pub const MAXNAMLEN = 511;
265
266pub const dirent = extern struct {
267 /// Inode number of entry.
268 d_ino: ino_t,
269 /// Offset of this entry on disk.
270 d_off: off_t,
271 /// Length of this record.
272 d_reclen: u16,
273 /// File name.
274 d_name: [MAXNAMLEN:0]u8,
275
276 pub fn reclen(self: dirent) u16 {
277 return self.d_reclen;
278 }
279};
280
281pub const SOCK = struct {
282 /// Datagram.
283 pub const DGRAM = 1;
284 /// STREAM.
285 pub const STREAM = 2;
286 /// Raw-protocol interface.
287 pub const RAW = 4;
288 /// Reliably-delivered message.
289 pub const RDM = 5;
290 /// Sequenced packed stream.
291 pub const SEQPACKET = 6;
292
293 pub const NONBLOCK = 0x100000;
294 pub const NDELAY = 0x200000;
295 pub const CLOEXEC = 0x080000;
296};
297
298pub const SO = struct {
299 pub const DEBUG = 0x0001;
300 pub const ACCEPTCONN = 0x0002;
301 pub const REUSEADDR = 0x0004;
302 pub const KEEPALIVE = 0x0008;
303 pub const DONTROUTE = 0x0010;
304 pub const BROADCAST = 0x0020;
305 pub const USELOOPBACK = 0x0040;
306 pub const LINGER = 0x0080;
307 pub const OOBINLINE = 0x0100;
308 pub const DGRAM_ERRIND = 0x0200;
309 pub const RECVUCRED = 0x0400;
310
311 pub const SNDBUF = 0x1001;
312 pub const RCVBUF = 0x1002;
313 pub const SNDLOWAT = 0x1003;
314 pub const RCVLOWAT = 0x1004;
315 pub const SNDTIMEO = 0x1005;
316 pub const RCVTIMEO = 0x1006;
317 pub const ERROR = 0x1007;
318 pub const TYPE = 0x1008;
319 pub const PROTOTYPE = 0x1009;
320 pub const ANON_MLP = 0x100a;
321 pub const MAC_EXEMPT = 0x100b;
322 pub const DOMAIN = 0x100c;
323 pub const RCVPSH = 0x100d;
324
325 pub const SECATTR = 0x1011;
326 pub const TIMESTAMP = 0x1013;
327 pub const ALLZONES = 0x1014;
328 pub const EXCLBIND = 0x1015;
329 pub const MAC_IMPLICIT = 0x1016;
330 pub const VRRP = 0x1017;
331};
332
333pub const SOMAXCONN = 128;
334
335pub const SCM = struct {
336 pub const UCRED = 0x1012;
337 pub const RIGHTS = 0x1010;
338 pub const TIMESTAMP = SO.TIMESTAMP;
339};
340
341pub const AF = struct {
342 pub const UNSPEC = 0;
343 pub const UNIX = 1;
344 pub const LOCAL = UNIX;
345 pub const FILE = UNIX;
346 pub const INET = 2;
347 pub const IMPLINK = 3;
348 pub const PUP = 4;
349 pub const CHAOS = 5;
350 pub const NS = 6;
351 pub const NBS = 7;
352 pub const ECMA = 8;
353 pub const DATAKIT = 9;
354 pub const CCITT = 10;
355 pub const SNA = 11;
356 pub const DECnet = 12;
357 pub const DLI = 13;
358 pub const LAT = 14;
359 pub const HYLINK = 15;
360 pub const APPLETALK = 16;
361 pub const NIT = 17;
362 pub const @"802" = 18;
363 pub const OSI = 19;
364 pub const X25 = 20;
365 pub const OSINET = 21;
366 pub const GOSIP = 22;
367 pub const IPX = 23;
368 pub const ROUTE = 24;
369 pub const LINK = 25;
370 pub const INET6 = 26;
371 pub const KEY = 27;
372 pub const NCA = 28;
373 pub const POLICY = 29;
374 pub const INET_OFFLOAD = 30;
375 pub const TRILL = 31;
376 pub const PACKET = 32;
377 pub const LX_NETLINK = 33;
378 pub const MAX = 33;
379};
380
381pub const SOL = struct {
382 pub const SOCKET = 0xffff;
383 pub const ROUTE = 0xfffe;
384 pub const PACKET = 0xfffd;
385 pub const FILTER = 0xfffc;
386};
387
388pub const PF = struct {
389 pub const UNSPEC = AF.UNSPEC;
390 pub const UNIX = AF.UNIX;
391 pub const LOCAL = UNIX;
392 pub const FILE = UNIX;
393 pub const INET = AF.INET;
394 pub const IMPLINK = AF.IMPLINK;
395 pub const PUP = AF.PUP;
396 pub const CHAOS = AF.CHAOS;
397 pub const NS = AF.NS;
398 pub const NBS = AF.NBS;
399 pub const ECMA = AF.ECMA;
400 pub const DATAKIT = AF.DATAKIT;
401 pub const CCITT = AF.CCITT;
402 pub const SNA = AF.SNA;
403 pub const DECnet = AF.DECnet;
404 pub const DLI = AF.DLI;
405 pub const LAT = AF.LAT;
406 pub const HYLINK = AF.HYLINK;
407 pub const APPLETALK = AF.APPLETALK;
408 pub const NIT = AF.NIT;
409 pub const @"802" = AF.@"802";
410 pub const OSI = AF.OSI;
411 pub const X25 = AF.X25;
412 pub const OSINET = AF.OSINET;
413 pub const GOSIP = AF.GOSIP;
414 pub const IPX = AF.IPX;
415 pub const ROUTE = AF.ROUTE;
416 pub const LINK = AF.LINK;
417 pub const INET6 = AF.INET6;
418 pub const KEY = AF.KEY;
419 pub const NCA = AF.NCA;
420 pub const POLICY = AF.POLICY;
421 pub const TRILL = AF.TRILL;
422 pub const PACKET = AF.PACKET;
423 pub const LX_NETLINK = AF.LX_NETLINK;
424 pub const MAX = AF.MAX;
425};
426
427pub const in_port_t = u16;
428pub const sa_family_t = u16;
429
430pub const sockaddr = extern struct {
431 /// address family
432 family: sa_family_t,
433
434 /// actually longer; address value
435 data: [14]u8,
436
437 pub const SS_MAXSIZE = 256;
438 pub const storage = std.x.os.Socket.Address.Native.Storage;
439
440 pub const in = extern struct {
441 family: sa_family_t = AF.INET,
442 port: in_port_t,
443 addr: u32,
444 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
445 };
446
447 pub const in6 = extern struct {
448 family: sa_family_t = AF.INET6,
449 port: in_port_t,
450 flowinfo: u32,
451 addr: [16]u8,
452 scope_id: u32,
453 __src_id: u32 = 0,
454 };
455
456 /// Definitions for UNIX IPC domain.
457 pub const un = extern struct {
458 family: sa_family_t = AF.UNIX,
459 path: [108]u8,
460 };
461};
462
463pub const AI = struct {
464 /// IPv4-mapped IPv6 address
465 pub const V4MAPPED = 0x0001;
466 pub const ALL = 0x0002;
467 /// only if any address is assigned
468 pub const ADDRCONFIG = 0x0004;
469 /// get address to use bind()
470 pub const PASSIVE = 0x0008;
471 /// fill ai_canonname
472 pub const CANONNAME = 0x0010;
473 /// prevent host name resolution
474 pub const NUMERICHOST = 0x0020;
475 /// prevent service name resolution
476 pub const NUMERICSERV = 0x0040;
477};
478
479pub const NI = struct {
480 pub const NOFQDN = 0x0001;
481 pub const NUMERICHOST = 0x0002;
482 pub const NAMEREQD = 0x0004;
483 pub const NUMERICSERV = 0x0008;
484 pub const DGRAM = 0x0010;
485 pub const WITHSCOPEID = 0x0020;
486 pub const NUMERICSCOPE = 0x0040;
487
488 pub const MAXHOST = 1025;
489 pub const MAXSERV = 32;
490};
491
492pub const PATH_MAX = 1024;
493pub const IOV_MAX = 1024;
494
495pub const STDIN_FILENO = 0;
496pub const STDOUT_FILENO = 1;
497pub const STDERR_FILENO = 2;
498
499pub const PROT = struct {
500 pub const NONE = 0;
501 pub const READ = 1;
502 pub const WRITE = 2;
503 pub const EXEC = 4;
504};
505
506pub const CLOCK = struct {
507 pub const VIRTUAL = 1;
508 pub const THREAD_CPUTIME_ID = 2;
509 pub const REALTIME = 3;
510 pub const MONOTONIC = 4;
511 pub const PROCESS_CPUTIME_ID = 5;
512 pub const HIGHRES = MONOTONIC;
513 pub const PROF = THREAD_CPUTIME_ID;
514};
515
516pub const MAP = struct {
517 pub const FAILED = @intToPtr(*c_void, maxInt(usize));
518 pub const SHARED = 0x0001;
519 pub const PRIVATE = 0x0002;
520 pub const TYPE = 0x000f;
521
522 pub const FILE = 0x0000;
523 pub const FIXED = 0x0010;
524 // Unimplemented
525 pub const RENAME = 0x0020;
526 pub const NORESERVE = 0x0040;
527 /// Force mapping in lower 4G address space
528 pub const @"32BIT" = 0x0080;
529
530 pub const ANON = 0x0100;
531 pub const ANONYMOUS = ANON;
532 pub const ALIGN = 0x0200;
533 pub const TEXT = 0x0400;
534 pub const INITDATA = 0x0800;
535};
536
537pub const MADV = struct {
538 /// no further special treatment
539 pub const NORMAL = 0;
540 /// expect random page references
541 pub const RANDOM = 1;
542 /// expect sequential page references
543 pub const SEQUENTIAL = 2;
544 /// will need these pages
545 pub const WILLNEED = 3;
546 /// don't need these pages
547 pub const DONTNEED = 4;
548 /// contents can be freed
549 pub const FREE = 5;
550 /// default access
551 pub const ACCESS_DEFAULT = 6;
552 /// next LWP to access heavily
553 pub const ACCESS_LWP = 7;
554 /// many processes to access heavily
555 pub const ACCESS_MANY = 8;
556 /// contents will be purged
557 pub const PURGE = 9;
558};
559
560pub const W = struct {
561 pub const EXITED = 0o001;
562 pub const TRAPPED = 0o002;
563 pub const UNTRACED = 0o004;
564 pub const STOPPED = UNTRACED;
565 pub const CONTINUED = 0o010;
566 pub const NOHANG = 0o100;
567 pub const NOWAIT = 0o200;
568
569 pub fn EXITSTATUS(s: u32) u8 {
570 return @intCast(u8, (s >> 8) & 0xff);
571 }
572 pub fn TERMSIG(s: u32) u32 {
573 return s & 0x7f;
574 }
575 pub fn STOPSIG(s: u32) u32 {
576 return EXITSTATUS(s);
577 }
578 pub fn IFEXITED(s: u32) bool {
579 return TERMSIG(s) == 0;
580 }
581
582 pub fn IFCONTINUED(s: u32) bool {
583 return ((s & 0o177777) == 0o177777);
584 }
585
586 pub fn IFSTOPPED(s: u32) bool {
587 return (s & 0x00ff != 0o177) and !(s & 0xff00 != 0);
588 }
589
590 pub fn IFSIGNALED(s: u32) bool {
591 return s & 0x00ff > 0 and s & 0xff00 == 0;
592 }
593};
594
595pub const SA = struct {
596 pub const ONSTACK = 0x00000001;
597 pub const RESETHAND = 0x00000002;
598 pub const RESTART = 0x00000004;
599 pub const SIGINFO = 0x00000008;
600 pub const NODEFER = 0x00000010;
601 pub const NOCLDWAIT = 0x00010000;
602};
603
604// access function
605pub const F_OK = 0; // test for existence of file
606pub const X_OK = 1; // test for execute or search permission
607pub const W_OK = 2; // test for write permission
608pub const R_OK = 4; // test for read permission
609
610pub const F = struct {
611 /// Unlock a previously locked region
612 pub const ULOCK = 0;
613 /// Lock a region for exclusive use
614 pub const LOCK = 1;
615 /// Test and lock a region for exclusive use
616 pub const TLOCK = 2;
617 /// Test a region for other processes locks
618 pub const TEST = 3;
619
620 /// Duplicate fildes
621 pub const DUPFD = 0;
622 /// Get fildes flags
623 pub const GETFD = 1;
624 /// Set fildes flags
625 pub const SETFD = 2;
626 /// Get file flags
627 pub const GETFL = 3;
628 /// Get file flags including open-only flags
629 pub const GETXFL = 45;
630 /// Set file flags
631 pub const SETFL = 4;
632
633 /// Unused
634 pub const CHKFL = 8;
635 /// Duplicate fildes at third arg
636 pub const DUP2FD = 9;
637 /// Like DUP2FD with O_CLOEXEC set EINVAL is fildes matches arg1
638 pub const DUP2FD_CLOEXEC = 36;
639 /// Like DUPFD with O_CLOEXEC set
640 pub const DUPFD_CLOEXEC = 37;
641
642 /// Is the file desc. a stream ?
643 pub const ISSTREAM = 13;
644 /// Turn on private access to file
645 pub const PRIV = 15;
646 /// Turn off private access to file
647 pub const NPRIV = 16;
648 /// UFS quota call
649 pub const QUOTACTL = 17;
650 /// Get number of BLKSIZE blocks allocated
651 pub const BLOCKS = 18;
652 /// Get optimal I/O block size
653 pub const BLKSIZE = 19;
654 /// Get owner (socket emulation)
655 pub const GETOWN = 23;
656 /// Set owner (socket emulation)
657 pub const SETOWN = 24;
658 /// Object reuse revoke access to file desc.
659 pub const REVOKE = 25;
660 /// Does vp have NFS locks private to lock manager
661 pub const HASREMOTELOCKS = 26;
662
663 /// Set file lock
664 pub const SETLK = 6;
665 /// Set file lock and wait
666 pub const SETLKW = 7;
667 /// Allocate file space
668 pub const ALLOCSP = 10;
669 /// Free file space
670 pub const FREESP = 11;
671 /// Get file lock
672 pub const GETLK = 14;
673 /// Get file lock owned by file
674 pub const OFD_GETLK = 47;
675 /// Set file lock owned by file
676 pub const OFD_SETLK = 48;
677 /// Set file lock owned by file and wait
678 pub const OFD_SETLKW = 49;
679 /// Set a file share reservation
680 pub const SHARE = 40;
681 /// Remove a file share reservation
682 pub const UNSHARE = 41;
683 /// Create Poison FD
684 pub const BADFD = 46;
685
686 /// Read lock
687 pub const RDLCK = 1;
688 /// Write lock
689 pub const WRLCK = 2;
690 /// Remove lock(s)
691 pub const UNLCK = 3;
692 /// remove remote locks for a given system
693 pub const UNLKSYS = 4;
694
695 // f_access values
696 /// Read-only share access
697 pub const RDACC = 0x1;
698 /// Write-only share access
699 pub const WRACC = 0x2;
700 /// Read-Write share access
701 pub const RWACC = 0x3;
702
703 // f_deny values
704 /// Don't deny others access
705 pub const NODNY = 0x0;
706 /// Deny others read share access
707 pub const RDDNY = 0x1;
708 /// Deny others write share access
709 pub const WRDNY = 0x2;
710 /// Deny others read or write share access
711 pub const RWDNY = 0x3;
712 /// private flag: Deny delete share access
713 pub const RMDNY = 0x4;
714};
715
716pub const O = struct {
717 pub const RDONLY = 0;
718 pub const WRONLY = 1;
719 pub const RDWR = 2;
720 pub const SEARCH = 0x200000;
721 pub const EXEC = 0x400000;
722 pub const NDELAY = 0x04;
723 pub const APPEND = 0x08;
724 pub const SYNC = 0x10;
725 pub const DSYNC = 0x40;
726 pub const RSYNC = 0x8000;
727 pub const NONBLOCK = 0x80;
728 pub const LARGEFILE = 0x2000;
729
730 pub const CREAT = 0x100;
731 pub const TRUNC = 0x200;
732 pub const EXCL = 0x400;
733 pub const NOCTTY = 0x800;
734 pub const XATTR = 0x4000;
735 pub const NOFOLLOW = 0x20000;
736 pub const NOLINKS = 0x40000;
737 pub const CLOEXEC = 0x800000;
738 pub const DIRECTORY = 0x1000000;
739 pub const DIRECT = 0x2000000;
740};
741
742pub const LOCK = struct {
743 pub const SH = 1;
744 pub const EX = 2;
745 pub const NB = 4;
746 pub const UN = 8;
747};
748
749pub const FD_CLOEXEC = 1;
750
751pub const SEEK = struct {
752 pub const SET = 0;
753 pub const CUR = 1;
754 pub const END = 2;
755 pub const DATA = 3;
756 pub const HOLE = 4;
757};
758
759pub const tcflag_t = c_uint;
760pub const cc_t = u8;
761pub const speed_t = c_uint;
762
763pub const NCCS = 19;
764
765pub const termios = extern struct {
766 c_iflag: tcflag_t,
767 c_oflag: tcflag_t,
768 c_cflag: tcflag_t,
769 c_lflag: tcflag_t,
770 c_cc: [NCCS]cc_t,
771};
772
773fn tioc(t: u16, num: u8) u16 {
774 return (t << 8) | num;
775}
776
777pub const T = struct {
778 pub const CGETA = tioc('T', 1);
779 pub const CSETA = tioc('T', 2);
780 pub const CSETAW = tioc('T', 3);
781 pub const CSETAF = tioc('T', 4);
782 pub const CSBRK = tioc('T', 5);
783 pub const CXONC = tioc('T', 6);
784 pub const CFLSH = tioc('T', 7);
785 pub const IOCGWINSZ = tioc('T', 104);
786 pub const IOCSWINSZ = tioc('T', 103);
787 // Softcarrier ioctls
788 pub const IOCGSOFTCAR = tioc('T', 105);
789 pub const IOCSSOFTCAR = tioc('T', 106);
790 // termios ioctls
791 pub const CGETS = tioc('T', 13);
792 pub const CSETS = tioc('T', 14);
793 pub const CSANOW = tioc('T', 14);
794 pub const CSETSW = tioc('T', 15);
795 pub const CSADRAIN = tioc('T', 15);
796 pub const CSETSF = tioc('T', 16);
797 pub const IOCSETLD = tioc('T', 123);
798 pub const IOCGETLD = tioc('T', 124);
799 // NTP PPS ioctls
800 pub const IOCGPPS = tioc('T', 125);
801 pub const IOCSPPS = tioc('T', 126);
802 pub const IOCGPPSEV = tioc('T', 127);
803
804 pub const IOCGETD = tioc('t', 0);
805 pub const IOCSETD = tioc('t', 1);
806 pub const IOCHPCL = tioc('t', 2);
807 pub const IOCGETP = tioc('t', 8);
808 pub const IOCSETP = tioc('t', 9);
809 pub const IOCSETN = tioc('t', 10);
810 pub const IOCEXCL = tioc('t', 13);
811 pub const IOCNXCL = tioc('t', 14);
812 pub const IOCFLUSH = tioc('t', 16);
813 pub const IOCSETC = tioc('t', 17);
814 pub const IOCGETC = tioc('t', 18);
815 /// bis local mode bits
816 pub const IOCLBIS = tioc('t', 127);
817 /// bic local mode bits
818 pub const IOCLBIC = tioc('t', 126);
819 /// set entire local mode word
820 pub const IOCLSET = tioc('t', 125);
821 /// get local modes
822 pub const IOCLGET = tioc('t', 124);
823 /// set break bit
824 pub const IOCSBRK = tioc('t', 123);
825 /// clear break bit
826 pub const IOCCBRK = tioc('t', 122);
827 /// set data terminal ready
828 pub const IOCSDTR = tioc('t', 121);
829 /// clear data terminal ready
830 pub const IOCCDTR = tioc('t', 120);
831 /// set local special chars
832 pub const IOCSLTC = tioc('t', 117);
833 /// get local special chars
834 pub const IOCGLTC = tioc('t', 116);
835 /// driver output queue size
836 pub const IOCOUTQ = tioc('t', 115);
837 /// void tty association
838 pub const IOCNOTTY = tioc('t', 113);
839 /// get a ctty
840 pub const IOCSCTTY = tioc('t', 132);
841 /// stop output, like ^S
842 pub const IOCSTOP = tioc('t', 111);
843 /// start output, like ^Q
844 pub const IOCSTART = tioc('t', 110);
845 /// get pgrp of tty
846 pub const IOCGPGRP = tioc('t', 20);
847 /// set pgrp of tty
848 pub const IOCSPGRP = tioc('t', 21);
849 /// get session id on ctty
850 pub const IOCGSID = tioc('t', 22);
851 /// simulate terminal input
852 pub const IOCSTI = tioc('t', 23);
853 /// set all modem bits
854 pub const IOCMSET = tioc('t', 26);
855 /// bis modem bits
856 pub const IOCMBIS = tioc('t', 27);
857 /// bic modem bits
858 pub const IOCMBIC = tioc('t', 28);
859 /// get all modem bits
860 pub const IOCMGET = tioc('t', 29);
861};
862
863pub const winsize = extern struct {
864 ws_row: u16,
865 ws_col: u16,
866 ws_xpixel: u16,
867 ws_ypixel: u16,
868};
869
870const NSIG = 75;
871
872pub const SIG = struct {
873 pub const DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
874 pub const ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
875 pub const IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
876 pub const HOLD = @intToPtr(?Sigaction.sigaction_fn, 2);
877
878 pub const WORDS = 4;
879 pub const MAXSIG = 75;
880
881 pub const SIG_BLOCK = 1;
882 pub const SIG_UNBLOCK = 2;
883 pub const SIG_SETMASK = 3;
884
885 pub const HUP = 1;
886 pub const INT = 2;
887 pub const QUIT = 3;
888 pub const ILL = 4;
889 pub const TRAP = 5;
890 pub const IOT = 6;
891 pub const ABRT = 6;
892 pub const EMT = 7;
893 pub const FPE = 8;
894 pub const KILL = 9;
895 pub const BUS = 10;
896 pub const SEGV = 11;
897 pub const SYS = 12;
898 pub const PIPE = 13;
899 pub const ALRM = 14;
900 pub const TERM = 15;
901 pub const USR1 = 16;
902 pub const USR2 = 17;
903 pub const CLD = 18;
904 pub const CHLD = 18;
905 pub const PWR = 19;
906 pub const WINCH = 20;
907 pub const URG = 21;
908 pub const POLL = 22;
909 pub const IO = .POLL;
910 pub const STOP = 23;
911 pub const TSTP = 24;
912 pub const CONT = 25;
913 pub const TTIN = 26;
914 pub const TTOU = 27;
915 pub const VTALRM = 28;
916 pub const PROF = 29;
917 pub const XCPU = 30;
918 pub const XFSZ = 31;
919 pub const WAITING = 32;
920 pub const LWP = 33;
921 pub const FREEZE = 34;
922 pub const THAW = 35;
923 pub const CANCEL = 36;
924 pub const LOST = 37;
925 pub const XRES = 38;
926 pub const JVM1 = 39;
927 pub const JVM2 = 40;
928 pub const INFO = 41;
929
930 pub const RTMIN = 42;
931 pub const RTMAX = 74;
932
933 pub inline fn IDX(sig: usize) usize {
934 return sig - 1;
935 }
936 pub inline fn WORD(sig: usize) usize {
937 return IDX(sig) >> 5;
938 }
939 pub inline fn BIT(sig: usize) usize {
940 return 1 << (IDX(sig) & 31);
941 }
942 pub inline fn VALID(sig: usize) usize {
943 return sig <= MAXSIG and sig > 0;
944 }
945};
946
947/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
948pub const Sigaction = extern struct {
949 pub const handler_fn = fn (c_int) callconv(.C) void;
950 pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
951
952 /// signal options
953 flags: c_uint,
954 /// signal handler
955 handler: extern union {
956 handler: ?handler_fn,
957 sigaction: ?sigaction_fn,
958 },
959 /// signal mask to apply
960 mask: sigset_t,
961};
962
963pub const sigval_t = extern union {
964 int: c_int,
965 ptr: ?*c_void,
966};
967
968pub const siginfo_t = extern struct {
969 signo: c_int,
970 code: c_int,
971 errno: c_int,
972 // 64bit architectures insert 4bytes of padding here, this is done by
973 // correctly aligning the reason field
974 reason: extern union {
975 proc: extern struct {
976 pid: pid_t,
977 pdata: extern union {
978 kill: extern struct {
979 uid: uid_t,
980 value: sigval_t,
981 },
982 cld: extern struct {
983 utime: clock_t,
984 status: c_int,
985 stime: clock_t,
986 },
987 },
988 contract: ctid_t,
989 zone: zoneid_t,
990 },
991 fault: extern struct {
992 addr: ?*c_void,
993 trapno: c_int,
994 pc: ?*c_void,
995 },
996 file: extern struct {
997 // fd not currently available for SIGPOLL.
998 fd: c_int,
999 band: c_long,
1000 },
1001 prof: extern struct {
1002 addr: ?*c_void,
1003 timestamp: timespec,
1004 syscall: c_short,
1005 sysarg: u8,
1006 fault: u8,
1007 args: [8]c_long,
1008 state: [10]c_int,
1009 },
1010 rctl: extern struct {
1011 entity: i32,
1012 },
1013 __pad: [256 - 4 * @sizeOf(c_int)]u8,
1014 } align(@sizeOf(usize)),
1015};
1016
1017comptime {
1018 std.debug.assert(@sizeOf(siginfo_t) == 256);
1019 std.debug.assert(@alignOf(siginfo_t) == @sizeOf(usize));
1020}
1021
1022pub const sigset_t = extern struct {
1023 __bits: [SIG.WORDS]u32,
1024};
1025
1026pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** SIG.WORDS };
1027
1028pub const fpregset_t = extern union {
1029 regs: [130]u32,
1030 chip_state: extern struct {
1031 cw: u16,
1032 sw: u16,
1033 fctw: u8,
1034 __fx_rsvd: u8,
1035 fop: u16,
1036 rip: u64,
1037 rdp: u64,
1038 mxcsr: u32,
1039 mxcsr_mask: u32,
1040 st: [8]extern union {
1041 fpr_16: [5]u16,
1042 __fpr_pad: u128,
1043 },
1044 xmm: [16]u128,
1045 __fx_ign2: [6]u128,
1046 status: u32,
1047 xstatus: u32,
1048 },
1049};
1050
1051pub const mcontext_t = extern struct {
1052 gregs: [28]u64,
1053 fpregs: fpregset_t,
1054};
1055
1056pub const REG = struct {
1057 pub const RBP = 10;
1058 pub const RIP = 17;
1059 pub const RSP = 20;
1060};
1061
1062pub const ucontext_t = extern struct {
1063 flags: u64,
1064 link: ?*ucontext_t,
1065 sigmask: sigset_t,
1066 stack: stack_t,
1067 mcontext: mcontext_t,
1068 brand_data: [3]?*c_void,
1069 filler: [2]i64,
1070};
1071
1072pub const GETCONTEXT = 0;
1073pub const SETCONTEXT = 1;
1074pub const GETUSTACK = 2;
1075pub const SETUSTACK = 3;
1076
1077pub const E = enum(u16) {
1078 /// No error occurred.
1079 SUCCESS = 0,
1080 /// Not super-user
1081 PERM = 1,
1082 /// No such file or directory
1083 NOENT = 2,
1084 /// No such process
1085 SRCH = 3,
1086 /// interrupted system call
1087 INTR = 4,
1088 /// I/O error
1089 IO = 5,
1090 /// No such device or address
1091 NXIO = 6,
1092 /// Arg list too long
1093 @"2BIG" = 7,
1094 /// Exec format error
1095 NOEXEC = 8,
1096 /// Bad file number
1097 BADF = 9,
1098 /// No children
1099 CHILD = 10,
1100 /// Resource temporarily unavailable.
1101 /// also: WOULDBLOCK: Operation would block.
1102 AGAIN = 11,
1103 /// Not enough core
1104 NOMEM = 12,
1105 /// Permission denied
1106 ACCES = 13,
1107 /// Bad address
1108 FAULT = 14,
1109 /// Block device required
1110 NOTBLK = 15,
1111 /// Mount device busy
1112 BUSY = 16,
1113 /// File exists
1114 EXIST = 17,
1115 /// Cross-device link
1116 XDEV = 18,
1117 /// No such device
1118 NODEV = 19,
1119 /// Not a directory
1120 NOTDIR = 20,
1121 /// Is a directory
1122 ISDIR = 21,
1123 /// Invalid argument
1124 INVAL = 22,
1125 /// File table overflow
1126 NFILE = 23,
1127 /// Too many open files
1128 MFILE = 24,
1129 /// Inappropriate ioctl for device
1130 NOTTY = 25,
1131 /// Text file busy
1132 TXTBSY = 26,
1133 /// File too large
1134 FBIG = 27,
1135 /// No space left on device
1136 NOSPC = 28,
1137 /// Illegal seek
1138 SPIPE = 29,
1139 /// Read only file system
1140 ROFS = 30,
1141 /// Too many links
1142 MLINK = 31,
1143 /// Broken pipe
1144 PIPE = 32,
1145 /// Math arg out of domain of func
1146 DOM = 33,
1147 /// Math result not representable
1148 RANGE = 34,
1149 /// No message of desired type
1150 NOMSG = 35,
1151 /// Identifier removed
1152 IDRM = 36,
1153 /// Channel number out of range
1154 CHRNG = 37,
1155 /// Level 2 not synchronized
1156 L2NSYNC = 38,
1157 /// Level 3 halted
1158 L3HLT = 39,
1159 /// Level 3 reset
1160 L3RST = 40,
1161 /// Link number out of range
1162 LNRNG = 41,
1163 /// Protocol driver not attached
1164 UNATCH = 42,
1165 /// No CSI structure available
1166 NOCSI = 43,
1167 /// Level 2 halted
1168 L2HLT = 44,
1169 /// Deadlock condition.
1170 DEADLK = 45,
1171 /// No record locks available.
1172 NOLCK = 46,
1173 /// Operation canceled
1174 CANCELED = 47,
1175 /// Operation not supported
1176 NOTSUP = 48,
1177
1178 // Filesystem Quotas
1179 /// Disc quota exceeded
1180 DQUOT = 49,
1181
1182 // Convergent Error Returns
1183 /// invalid exchange
1184 BADE = 50,
1185 /// invalid request descriptor
1186 BADR = 51,
1187 /// exchange full
1188 XFULL = 52,
1189 /// no anode
1190 NOANO = 53,
1191 /// invalid request code
1192 BADRQC = 54,
1193 /// invalid slot
1194 BADSLT = 55,
1195 /// file locking deadlock error
1196 DEADLOCK = 56,
1197 /// bad font file fmt
1198 BFONT = 57,
1199
1200 // Interprocess Robust Locks
1201 /// process died with the lock
1202 OWNERDEAD = 58,
1203 /// lock is not recoverable
1204 NOTRECOVERABLE = 59,
1205 /// locked lock was unmapped
1206 LOCKUNMAPPED = 72,
1207 /// Facility is not active
1208 NOTACTIVE = 73,
1209 /// multihop attempted
1210 MULTIHOP = 74,
1211 /// trying to read unreadable message
1212 BADMSG = 77,
1213 /// path name is too long
1214 NAMETOOLONG = 78,
1215 /// value too large to be stored in data type
1216 OVERFLOW = 79,
1217 /// given log. name not unique
1218 NOTUNIQ = 80,
1219 /// f.d. invalid for this operation
1220 BADFD = 81,
1221 /// Remote address changed
1222 REMCHG = 82,
1223
1224 // Stream Problems
1225 /// Device not a stream
1226 NOSTR = 60,
1227 /// no data (for no delay io)
1228 NODATA = 61,
1229 /// timer expired
1230 TIME = 62,
1231 /// out of streams resources
1232 NOSR = 63,
1233 /// Machine is not on the network
1234 NONET = 64,
1235 /// Package not installed
1236 NOPKG = 65,
1237 /// The object is remote
1238 REMOTE = 66,
1239 /// the link has been severed
1240 NOLINK = 67,
1241 /// advertise error
1242 ADV = 68,
1243 /// srmount error
1244 SRMNT = 69,
1245 /// Communication error on send
1246 COMM = 70,
1247 /// Protocol error
1248 PROTO = 71,
1249
1250 // Shared Library Problems
1251 /// Can't access a needed shared lib.
1252 LIBACC = 83,
1253 /// Accessing a corrupted shared lib.
1254 LIBBAD = 84,
1255 /// .lib section in a.out corrupted.
1256 LIBSCN = 85,
1257 /// Attempting to link in too many libs.
1258 LIBMAX = 86,
1259 /// Attempting to exec a shared library.
1260 LIBEXEC = 87,
1261 /// Illegal byte sequence.
1262 ILSEQ = 88,
1263 /// Unsupported file system operation
1264 NOSYS = 89,
1265 /// Symbolic link loop
1266 LOOP = 90,
1267 /// Restartable system call
1268 RESTART = 91,
1269 /// if pipe/FIFO, don't sleep in stream head
1270 STRPIPE = 92,
1271 /// directory not empty
1272 NOTEMPTY = 93,
1273 /// Too many users (for UFS)
1274 USERS = 94,
1275
1276 // BSD Networking Software
1277 // Argument Errors
1278 /// Socket operation on non-socket
1279 NOTSOCK = 95,
1280 /// Destination address required
1281 DESTADDRREQ = 96,
1282 /// Message too long
1283 MSGSIZE = 97,
1284 /// Protocol wrong type for socket
1285 PROTOTYPE = 98,
1286 /// Protocol not available
1287 NOPROTOOPT = 99,
1288 /// Protocol not supported
1289 PROTONOSUPPORT = 120,
1290 /// Socket type not supported
1291 SOCKTNOSUPPORT = 121,
1292 /// Operation not supported on socket
1293 OPNOTSUPP = 122,
1294 /// Protocol family not supported
1295 PFNOSUPPORT = 123,
1296 /// Address family not supported by
1297 AFNOSUPPORT = 124,
1298 /// Address already in use
1299 ADDRINUSE = 125,
1300 /// Can't assign requested address
1301 ADDRNOTAVAIL = 126,
1302
1303 // Operational Errors
1304 /// Network is down
1305 NETDOWN = 127,
1306 /// Network is unreachable
1307 NETUNREACH = 128,
1308 /// Network dropped connection because
1309 NETRESET = 129,
1310 /// Software caused connection abort
1311 CONNABORTED = 130,
1312 /// Connection reset by peer
1313 CONNRESET = 131,
1314 /// No buffer space available
1315 NOBUFS = 132,
1316 /// Socket is already connected
1317 ISCONN = 133,
1318 /// Socket is not connected
1319 NOTCONN = 134,
1320 /// Can't send after socket shutdown
1321 SHUTDOWN = 143,
1322 /// Too many references: can't splice
1323 TOOMANYREFS = 144,
1324 /// Connection timed out
1325 TIMEDOUT = 145,
1326 /// Connection refused
1327 CONNREFUSED = 146,
1328 /// Host is down
1329 HOSTDOWN = 147,
1330 /// No route to host
1331 HOSTUNREACH = 148,
1332 /// operation already in progress
1333 ALREADY = 149,
1334 /// operation now in progress
1335 INPROGRESS = 150,
1336
1337 // SUN Network File System
1338 /// Stale NFS file handle
1339 STALE = 151,
1340
1341 _,
1342};
1343
1344pub const MINSIGSTKSZ = 2048;
1345pub const SIGSTKSZ = 8192;
1346
1347pub const SS_ONSTACK = 0x1;
1348pub const SS_DISABLE = 0x2;
1349
1350pub const stack_t = extern struct {
1351 sp: [*]u8,
1352 size: isize,
1353 flags: i32,
1354};
1355
1356pub const S = struct {
1357 pub const IFMT = 0o170000;
1358
1359 pub const IFIFO = 0o010000;
1360 pub const IFCHR = 0o020000;
1361 pub const IFDIR = 0o040000;
1362 pub const IFBLK = 0o060000;
1363 pub const IFREG = 0o100000;
1364 pub const IFLNK = 0o120000;
1365 pub const IFSOCK = 0o140000;
1366 /// SunOS 2.6 Door
1367 pub const IFDOOR = 0o150000;
1368 /// Solaris 10 Event Port
1369 pub const IFPORT = 0o160000;
1370
1371 pub const ISUID = 0o4000;
1372 pub const ISGID = 0o2000;
1373 pub const ISVTX = 0o1000;
1374 pub const IRWXU = 0o700;
1375 pub const IRUSR = 0o400;
1376 pub const IWUSR = 0o200;
1377 pub const IXUSR = 0o100;
1378 pub const IRWXG = 0o070;
1379 pub const IRGRP = 0o040;
1380 pub const IWGRP = 0o020;
1381 pub const IXGRP = 0o010;
1382 pub const IRWXO = 0o007;
1383 pub const IROTH = 0o004;
1384 pub const IWOTH = 0o002;
1385 pub const IXOTH = 0o001;
1386
1387 pub fn ISFIFO(m: u32) bool {
1388 return m & IFMT == IFIFO;
1389 }
1390
1391 pub fn ISCHR(m: u32) bool {
1392 return m & IFMT == IFCHR;
1393 }
1394
1395 pub fn ISDIR(m: u32) bool {
1396 return m & IFMT == IFDIR;
1397 }
1398
1399 pub fn ISBLK(m: u32) bool {
1400 return m & IFMT == IFBLK;
1401 }
1402
1403 pub fn ISREG(m: u32) bool {
1404 return m & IFMT == IFREG;
1405 }
1406
1407 pub fn ISLNK(m: u32) bool {
1408 return m & IFMT == IFLNK;
1409 }
1410
1411 pub fn ISSOCK(m: u32) bool {
1412 return m & IFMT == IFSOCK;
1413 }
1414
1415 pub fn ISDOOR(m: u32) bool {
1416 return m & IFMT == IFDOOR;
1417 }
1418
1419 pub fn ISPORT(m: u32) bool {
1420 return m & IFMT == IFPORT;
1421 }
1422};
1423
1424pub const AT = struct {
1425 /// Magic value that specify the use of the current working directory
1426 /// to determine the target of relative file paths in the openat() and
1427 /// similar syscalls.
1428 pub const FDCWD = @bitCast(fd_t, @as(u32, 0xffd19553));
1429
1430 /// Do not follow symbolic links
1431 pub const SYMLINK_NOFOLLOW = 0x1000;
1432 /// Follow symbolic link
1433 pub const SYMLINK_FOLLOW = 0x2000;
1434 /// Remove directory instead of file
1435 pub const REMOVEDIR = 0x1;
1436 pub const TRIGGER = 0x2;
1437 /// Check access using effective user and group ID
1438 pub const EACCESS = 0x4;
1439};
1440
1441pub const POSIX_FADV = struct {
1442 pub const NORMAL = 0;
1443 pub const RANDOM = 1;
1444 pub const SEQUENTIAL = 2;
1445 pub const WILLNEED = 3;
1446 pub const DONTNEED = 4;
1447 pub const NOREUSE = 5;
1448};
1449
1450pub const HOST_NAME_MAX = 255;
1451
1452pub const IPPROTO = struct {
1453 /// dummy for IP
1454 pub const IP = 0;
1455 /// Hop by hop header for IPv6
1456 pub const HOPOPTS = 0;
1457 /// control message protocol
1458 pub const ICMP = 1;
1459 /// group control protocol
1460 pub const IGMP = 2;
1461 /// gateway^2 (deprecated)
1462 pub const GGP = 3;
1463 /// IP in IP encapsulation
1464 pub const ENCAP = 4;
1465 /// tcp
1466 pub const TCP = 6;
1467 /// exterior gateway protocol
1468 pub const EGP = 8;
1469 /// pup
1470 pub const PUP = 12;
1471 /// user datagram protocol
1472 pub const UDP = 17;
1473 /// xns idp
1474 pub const IDP = 22;
1475 /// IPv6 encapsulated in IP
1476 pub const IPV6 = 41;
1477 /// Routing header for IPv6
1478 pub const ROUTING = 43;
1479 /// Fragment header for IPv6
1480 pub const FRAGMENT = 44;
1481 /// rsvp
1482 pub const RSVP = 46;
1483 /// IPsec Encap. Sec. Payload
1484 pub const ESP = 50;
1485 /// IPsec Authentication Hdr.
1486 pub const AH = 51;
1487 /// ICMP for IPv6
1488 pub const ICMPV6 = 58;
1489 /// No next header for IPv6
1490 pub const NONE = 59;
1491 /// Destination options
1492 pub const DSTOPTS = 60;
1493 /// "hello" routing protocol
1494 pub const HELLO = 63;
1495 /// UNOFFICIAL net disk proto
1496 pub const ND = 77;
1497 /// ISO clnp
1498 pub const EON = 80;
1499 /// OSPF
1500 pub const OSPF = 89;
1501 /// PIM routing protocol
1502 pub const PIM = 103;
1503 /// Stream Control
1504 pub const SCTP = 132;
1505 /// raw IP packet
1506 pub const RAW = 255;
1507 /// Sockets Direct Protocol
1508 pub const PROTO_SDP = 257;
1509};
1510
1511pub const priority = enum(c_int) {
1512 PROCESS = 0,
1513 PGRP = 1,
1514 USER = 2,
1515 GROUP = 3,
1516 SESSION = 4,
1517 LWP = 5,
1518 TASK = 6,
1519 PROJECT = 7,
1520 ZONE = 8,
1521 CONTRACT = 9,
1522};
1523
1524pub const rlimit_resource = enum(c_int) {
1525 CPU = 0,
1526 FSIZE = 1,
1527 DATA = 2,
1528 STACK = 3,
1529 CORE = 4,
1530 NOFILE = 5,
1531 VMEM = 6,
1532 _,
1533
1534 pub const AS: rlimit_resource = .VMEM;
1535};
1536
1537pub const rlim_t = u64;
1538
1539pub const RLIM = struct {
1540 /// No limit
1541 pub const INFINITY: rlim_t = (1 << 63) - 3;
1542 pub const SAVED_MAX: rlim_t = (1 << 63) - 2;
1543 pub const SAVED_CUR: rlim_t = (1 << 63) - 1;
1544};
1545
1546pub const rlimit = extern struct {
1547 /// Soft limit
1548 cur: rlim_t,
1549 /// Hard limit
1550 max: rlim_t,
1551};
1552
1553pub const RUSAGE_SELF = 0;
1554pub const RUSAGE_CHILDREN = -1;
1555pub const RUSAGE_THREAD = 1;
1556
1557pub const rusage = extern struct {
1558 utime: timeval,
1559 stime: timeval,
1560 maxrss: isize,
1561 ixrss: isize,
1562 idrss: isize,
1563 isrss: isize,
1564 minflt: isize,
1565 majflt: isize,
1566 nswap: isize,
1567 inblock: isize,
1568 oublock: isize,
1569 msgsnd: isize,
1570 msgrcv: isize,
1571 nsignals: isize,
1572 nvcsw: isize,
1573 nivcsw: isize,
1574};
1575
1576pub const SHUT = struct {
1577 pub const RD = 0;
1578 pub const WR = 1;
1579 pub const RDWR = 2;
1580};
1581
1582pub const pollfd = extern struct {
1583 fd: fd_t,
1584 events: i16,
1585 revents: i16,
1586};
1587
1588/// Testable events (may be specified in ::pollfd::events).
1589pub const POLL = struct {
1590 pub const IN = 0x0001;
1591 pub const PRI = 0x0002;
1592 pub const OUT = 0x0004;
1593 pub const RDNORM = 0x0040;
1594 pub const WRNORM = .OUT;
1595 pub const RDBAND = 0x0080;
1596 pub const WRBAND = 0x0100;
1597 /// Read-side hangup.
1598 pub const RDHUP = 0x4000;
1599
1600 /// Non-testable events (may not be specified in events).
1601 pub const ERR = 0x0008;
1602 pub const HUP = 0x0010;
1603 pub const NVAL = 0x0020;
1604
1605 /// Events to control `/dev/poll` (not specified in revents)
1606 pub const REMOVE = 0x0800;
1607 pub const ONESHOT = 0x1000;
1608 pub const ET = 0x2000;
1609};
1610
1611/// Extensions to the ELF auxiliary vector.
1612pub const AT_SUN = struct {
1613 /// effective user id
1614 pub const UID = 2000;
1615 /// real user id
1616 pub const RUID = 2001;
1617 /// effective group id
1618 pub const GID = 2002;
1619 /// real group id
1620 pub const RGID = 2003;
1621 /// dynamic linker's ELF header
1622 pub const LDELF = 2004;
1623 /// dynamic linker's section headers
1624 pub const LDSHDR = 2005;
1625 /// name of dynamic linker
1626 pub const LDNAME = 2006;
1627 /// large pagesize
1628 pub const LPAGESZ = 2007;
1629 /// platform name
1630 pub const PLATFORM = 2008;
1631 /// hints about hardware capabilities.
1632 pub const HWCAP = 2009;
1633 pub const HWCAP2 = 2023;
1634 /// flush icache?
1635 pub const IFLUSH = 2010;
1636 /// cpu name
1637 pub const CPU = 2011;
1638 /// exec() path name in the auxv, null terminated.
1639 pub const EXECNAME = 2014;
1640 /// mmu module name
1641 pub const MMU = 2015;
1642 /// dynamic linkers data segment
1643 pub const LDDATA = 2016;
1644 /// AF_SUN_ flags passed from the kernel
1645 pub const AUXFLAGS = 2017;
1646 /// name of the emulation binary for the linker
1647 pub const EMULATOR = 2018;
1648 /// name of the brand library for the linker
1649 pub const BRANDNAME = 2019;
1650 /// vectors for brand modules.
1651 pub const BRAND_AUX1 = 2020;
1652 pub const BRAND_AUX2 = 2021;
1653 pub const BRAND_AUX3 = 2022;
1654 pub const BRAND_AUX4 = 2025;
1655 pub const BRAND_NROOT = 2024;
1656 /// vector for comm page.
1657 pub const COMMPAGE = 2026;
1658 /// information about the x86 FPU.
1659 pub const FPTYPE = 2027;
1660 pub const FPSIZE = 2028;
1661};
1662
1663/// ELF auxiliary vector flags.
1664pub const AF_SUN = struct {
1665 /// tell ld.so.1 to run "secure" and ignore the environment.
1666 pub const SETUGID = 0x00000001;
1667 /// hardware capabilities can be verified against AT_SUN_HWCAP
1668 pub const HWCAPVERIFY = 0x00000002;
1669 pub const NOPLM = 0x00000004;
1670};
1671
1672// TODO: Add sysconf numbers when the other OSs do.
1673pub const _SC = struct {
1674 pub const NPROCESSORS_ONLN = 15;
1675};
1676
1677pub const procfs = struct {
1678 pub const misc_header = extern struct {
1679 size: u32,
1680 @"type": enum(u32) {
1681 Pathname,
1682 Socketname,
1683 Peersockname,
1684 SockoptsBoolOpts,
1685 SockoptLinger,
1686 SockoptSndbuf,
1687 SockoptRcvbuf,
1688 SockoptIpNexthop,
1689 SockoptIpv6Nexthop,
1690 SockoptType,
1691 SockoptTcpCongestion,
1692 SockfiltersPriv = 14,
1693 },
1694 };
1695
1696 pub const fdinfo = extern struct {
1697 fd: fd_t,
1698 mode: mode_t,
1699 ino: ino_t,
1700 size: off_t,
1701 offset: off_t,
1702 uid: uid_t,
1703 gid: gid_t,
1704 dev_major: major_t,
1705 dev_minor: minor_t,
1706 special_major: major_t,
1707 special_minor: minor_t,
1708 fileflags: i32,
1709 fdflags: i32,
1710 locktype: i16,
1711 lockpid: pid_t,
1712 locksysid: i32,
1713 peerpid: pid_t,
1714 __filler: [25]c_int,
1715 peername: [15:0]u8,
1716 misc: [1]u8,
1717 };
1718};
1719
1720pub const SFD = struct {
1721 pub const CLOEXEC = 0o2000000;
1722 pub const NONBLOCK = 0o4000;
1723};
1724
1725pub const signalfd_siginfo = extern struct {
1726 signo: u32,
1727 errno: i32,
1728 code: i32,
1729 pid: u32,
1730 uid: uid_t,
1731 fd: i32,
1732 tid: u32, // unused
1733 band: u32,
1734 overrun: u32, // unused
1735 trapno: u32,
1736 status: i32,
1737 int: i32, // unused
1738 ptr: u64, // unused
1739 utime: u64,
1740 stime: u64,
1741 addr: u64,
1742 __pad: [48]u8,
1743};
1744
1745pub const PORT_SOURCE = struct {
1746 pub const AIO = 1;
1747 pub const TIMER = 2;
1748 pub const USER = 3;
1749 pub const FD = 4;
1750 pub const ALERT = 5;
1751 pub const MQ = 6;
1752 pub const FILE = 7;
1753};
1754
1755pub const PORT_ALERT = struct {
1756 pub const SET = 0x01;
1757 pub const UPDATE = 0x02;
1758};
1759
1760/// User watchable file events.
1761pub const FILE_EVENT = struct {
1762 pub const ACCESS = 0x00000001;
1763 pub const MODIFIED = 0x00000002;
1764 pub const ATTRIB = 0x00000004;
1765 pub const DELETE = 0x00000010;
1766 pub const RENAME_TO = 0x00000020;
1767 pub const RENAME_FROM = 0x00000040;
1768 pub const TRUNC = 0x00100000;
1769 pub const NOFOLLOW = 0x10000000;
1770 /// The filesystem holding the watched file was unmounted.
1771 pub const UNMOUNTED = 0x20000000;
1772 /// Some other file/filesystem got mounted over the watched file/directory.
1773 pub const MOUNTEDOVER = 0x40000000;
1774
1775 pub fn isException(event: u32) bool {
1776 return event & (UNMOUNTED | DELETE | RENAME_TO | RENAME_FROM | MOUNTEDOVER) > 0;
1777 }
1778};
1779
1780pub const port_event = extern struct {
1781 events: u32,
1782 /// Event source.
1783 source: u16,
1784 __pad: u16,
1785 /// Source-specific object.
1786 object: ?*c_void,
1787 /// User cookie.
1788 cookie: ?*c_void,
1789};
1790
1791pub const port_notify = extern struct {
1792 /// Bind request(s) to port.
1793 port: u32,
1794 /// User defined variable.
1795 user: ?*void,
1796};
1797
1798pub const file_obj = extern struct {
1799 /// Access time.
1800 atim: timespec,
1801 /// Modification time
1802 mtim: timespec,
1803 /// Change time
1804 ctim: timespec,
1805 __pad: [3]usize,
1806 name: [*:0]u8,
1807};
1808
1809// struct ifreq is marked obsolete, with struct lifreq prefered for interface requests.
1810// Here we alias lifreq to ifreq to avoid chainging existing code in os and x.os.IPv6.
1811pub const SIOCGLIFINDEX = IOWR('i', 133, lifreq);
1812pub const SIOCGIFINDEX = SIOCGLIFINDEX;
1813pub const MAX_HDW_LEN = 64;
1814pub const IFNAMESIZE = 32;
1815
1816pub const lif_nd_req = extern struct {
1817 addr: sockaddr.storage,
1818 state_create: u8,
1819 state_same_lla: u8,
1820 state_diff_lla: u8,
1821 hdw_len: i32,
1822 flags: i32,
1823 __pad: i32,
1824 hdw_addr: [MAX_HDW_LEN]u8,
1825};
1826
1827pub const lif_ifinfo_req = extern struct {
1828 maxhops: u8,
1829 reachtime: u32,
1830 reachretrans: u32,
1831 maxmtu: u32,
1832};
1833
1834/// IP interface request. See if_tcp(7p) for more info.
1835pub const lifreq = extern struct {
1836 // Not actually in a union, but the stdlib expects one for ifreq
1837 ifrn: extern union {
1838 /// Interface name, e.g. "lo0", "en0".
1839 name: [IFNAMESIZE]u8,
1840 },
1841 ru1: extern union {
1842 /// For subnet/token etc.
1843 addrlen: i32,
1844 /// Driver's PPA (physical point of attachment).
1845 ppa: u32,
1846 },
1847 /// One of the IFT types, e.g. IFT_ETHER.
1848 @"type": u32,
1849 ifru: extern union {
1850 /// Address.
1851 addr: sockaddr.storage,
1852 /// Other end of a peer-to-peer link.
1853 dstaddr: sockaddr.storage,
1854 /// Broadcast address.
1855 broadaddr: sockaddr.storage,
1856 /// Address token.
1857 token: sockaddr.storage,
1858 /// Subnet prefix.
1859 subnet: sockaddr.storage,
1860 /// Interface index.
1861 ivalue: i32,
1862 /// Flags for SIOC?LIFFLAGS.
1863 flags: u64,
1864 /// Hop count metric
1865 metric: i32,
1866 /// Maximum transmission unit
1867 mtu: u32,
1868 // Technically [2]i32
1869 muxid: packed struct { ip: i32, arp: i32 },
1870 /// Neighbor reachability determination entries
1871 nd_req: lif_nd_req,
1872 /// Link info
1873 ifinfo_req: lif_ifinfo_req,
1874 /// Name of the multipath interface group
1875 groupname: [IFNAMESIZE]u8,
1876 binding: [IFNAMESIZE]u8,
1877 /// Zone id associated with this interface.
1878 zoneid: zoneid_t,
1879 /// Duplicate address detection state. Either in progress or completed.
1880 dadstate: u32,
1881 },
1882};
1883
1884pub const ifreq = lifreq;
1885
1886const IoCtlCommand = enum(u32) {
1887 none = 0x20000000, // no parameters
1888 write = 0x40000000, // copy out parameters
1889 read = 0x80000000, // copy in parameters
1890 read_write = 0xc0000000,
1891};
1892
1893fn ioImpl(cmd: IoCtlCommand, io_type: u8, nr: u8, comptime IOT: type) i32 {
1894 const size = @intCast(u32, @truncate(u8, @sizeOf(IOT))) << 16;
1895 const t = @intCast(u32, io_type) << 8;
1896 return @bitCast(i32, @enumToInt(cmd) | size | t | nr);
1897}
1898
1899pub fn IO(io_type: u8, nr: u8) i32 {
1900 return ioImpl(.none, io_type, nr, void);
1901}
1902
1903pub fn IOR(io_type: u8, nr: u8, comptime IOT: type) i32 {
1904 return ioImpl(.write, io_type, nr, IOT);
1905}
1906
1907pub fn IOW(io_type: u8, nr: u8, comptime IOT: type) i32 {
1908 return ioImpl(.read, io_type, nr, IOT);
1909}
1910
1911pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 {
1912 return ioImpl(.read_write, io_type, nr, IOT);
1913}
lib/std/debug.zig+6-4
......@@ -654,6 +654,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
654654 .openbsd,
655655 .macos,
656656 .windows,
657 .solaris,
657658 => return DebugInfo.init(allocator),
658659 else => return error.UnsupportedDebugInfo,
659660 }
......@@ -1420,7 +1421,7 @@ pub const ModuleDebugInfo = switch (native_os) {
14201421 };
14211422 }
14221423 },
1423 .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku => struct {
1424 .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris => struct {
14241425 base_address: usize,
14251426 dwarf: DW.DwarfInfo,
14261427 mapped_memory: []const u8,
......@@ -1468,7 +1469,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
14681469
14691470/// Whether or not the current target can print useful debug information when a segfault occurs.
14701471pub const have_segfault_handling_support = switch (native_os) {
1471 .linux, .netbsd => true,
1472 .linux, .netbsd, .solaris => true,
14721473 .windows => true,
14731474 .freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
14741475 else => false,
......@@ -1535,6 +1536,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
15351536 .freebsd => @ptrToInt(info.addr),
15361537 .netbsd => @ptrToInt(info.info.reason.fault.addr),
15371538 .openbsd => @ptrToInt(info.data.fault.addr),
1539 .solaris => @ptrToInt(info.reason.fault.addr),
15381540 else => unreachable,
15391541 };
15401542
......@@ -1559,13 +1561,13 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
15591561 .x86_64 => {
15601562 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
15611563 const ip = switch (native_os) {
1562 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
1564 .linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
15631565 .freebsd => @intCast(usize, ctx.mcontext.rip),
15641566 .openbsd => @intCast(usize, ctx.sc_rip),
15651567 else => unreachable,
15661568 };
15671569 const bp = switch (native_os) {
1568 .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
1570 .linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
15691571 .openbsd => @intCast(usize, ctx.sc_rbp),
15701572 .freebsd => @intCast(usize, ctx.mcontext.rbp),
15711573 else => unreachable,
lib/std/dynamic_library.zig+1-1
......@@ -14,7 +14,7 @@ const max = std.math.max;
1414pub const DynLib = switch (builtin.os.tag) {
1515 .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
1616 .windows => WindowsDynLib,
17 .macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly => DlDynlib,
17 .macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly, .solaris => DlDynlib,
1818 else => void,
1919};
2020
lib/std/fs.zig+61-4
......@@ -35,7 +35,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
3535/// fit into a UTF-8 encoded array of this length.
3636/// The byte count includes room for a null sentinel byte.
3737pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
38 .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => os.PATH_MAX,
38 .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku, .solaris => os.PATH_MAX,
3939 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
4040 // If it would require 4 UTF-8 bytes, then there would be a surrogate
4141 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
......@@ -298,10 +298,10 @@ pub const Dir = struct {
298298 pub const Kind = File.Kind;
299299 };
300300
301 const IteratorError = error{AccessDenied} || os.UnexpectedError;
301 const IteratorError = error{ AccessDenied, SystemResources } || os.UnexpectedError;
302302
303303 pub const Iterator = switch (builtin.os.tag) {
304 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
304 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => struct {
305305 dir: Dir,
306306 seek: i64,
307307 buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)),
......@@ -318,6 +318,7 @@ pub const Dir = struct {
318318 switch (builtin.os.tag) {
319319 .macos, .ios => return self.nextDarwin(),
320320 .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
321 .solaris => return self.nextSolaris(),
321322 else => @compileError("unimplemented"),
322323 }
323324 }
......@@ -372,6 +373,60 @@ pub const Dir = struct {
372373 }
373374 }
374375
376 fn nextSolaris(self: *Self) !?Entry {
377 start_over: while (true) {
378 if (self.index >= self.end_index) {
379 const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len);
380 switch (os.errno(rc)) {
381 .SUCCESS => {},
382 .BADF => unreachable, // Dir is invalid or was opened without iteration ability
383 .FAULT => unreachable,
384 .NOTDIR => unreachable,
385 .INVAL => unreachable,
386 else => |err| return os.unexpectedErrno(err),
387 }
388 if (rc == 0) return null;
389 self.index = 0;
390 self.end_index = @intCast(usize, rc);
391 }
392 const entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
393 const next_index = self.index + entry.reclen();
394 self.index = next_index;
395
396 const name = mem.spanZ(@ptrCast([*:0]u8, &entry.d_name));
397 if (mem.eql(u8, name, ".") or mem.eql(u8, name, ".."))
398 continue :start_over;
399
400 // Solaris dirent doesn't expose d_type, so we have to call stat to get it.
401 const stat_info = os.fstatat(
402 self.dir.fd,
403 name,
404 os.AT.SYMLINK_NOFOLLOW,
405 ) catch |err| switch (err) {
406 error.NameTooLong => unreachable,
407 error.SymLinkLoop => unreachable,
408 error.FileNotFound => unreachable, // lost the race
409 else => |e| return e,
410 };
411 const entry_kind = switch (stat_info.mode & os.S.IFMT) {
412 os.S.IFIFO => Entry.Kind.NamedPipe,
413 os.S.IFCHR => Entry.Kind.CharacterDevice,
414 os.S.IFDIR => Entry.Kind.Directory,
415 os.S.IFBLK => Entry.Kind.BlockDevice,
416 os.S.IFREG => Entry.Kind.File,
417 os.S.IFLNK => Entry.Kind.SymLink,
418 os.S.IFSOCK => Entry.Kind.UnixDomainSocket,
419 os.S.IFDOOR => Entry.Kind.Door,
420 os.S.IFPORT => Entry.Kind.EventPort,
421 else => Entry.Kind.Unknown,
422 };
423 return Entry{
424 .name = name,
425 .kind = entry_kind,
426 };
427 }
428 }
429
375430 fn nextBsd(self: *Self) !?Entry {
376431 start_over: while (true) {
377432 if (self.index >= self.end_index) {
......@@ -704,6 +759,7 @@ pub const Dir = struct {
704759 .netbsd,
705760 .dragonfly,
706761 .openbsd,
762 .solaris,
707763 => return Iterator{
708764 .dir = self,
709765 .seek = 0,
......@@ -1556,7 +1612,7 @@ pub const Dir = struct {
15561612 error.AccessDenied => |e| switch (builtin.os.tag) {
15571613 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
15581614 // we need to handle that case specifically and translate the error
1559 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
1615 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
15601616 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
15611617 const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT.SYMLINK_NOFOLLOW) catch return e;
15621618 const is_dir = fstat.mode & os.S.IFMT == os.S.IFDIR;
......@@ -2441,6 +2497,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
24412497 }
24422498 switch (builtin.os.tag) {
24432499 .linux => return os.readlinkZ("/proc/self/exe", out_buffer),
2500 .solaris => return os.readlinkZ("/proc/self/path/a.out", out_buffer),
24442501 .freebsd, .dragonfly => {
24452502 var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
24462503 var out_len: usize = out_buffer.len;
lib/std/fs/file.zig+32-18
......@@ -41,6 +41,8 @@ pub const File = struct {
4141 File,
4242 UnixDomainSocket,
4343 Whiteout,
44 Door,
45 EventPort,
4446 Unknown,
4547 };
4648
......@@ -320,28 +322,40 @@ pub const File = struct {
320322 const atime = st.atime();
321323 const mtime = st.mtime();
322324 const ctime = st.ctime();
325 const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {
326 .BLOCK_DEVICE => Kind.BlockDevice,
327 .CHARACTER_DEVICE => Kind.CharacterDevice,
328 .DIRECTORY => Kind.Directory,
329 .SYMBOLIC_LINK => Kind.SymLink,
330 .REGULAR_FILE => Kind.File,
331 .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket,
332 else => Kind.Unknown,
333 } else blk: {
334 const m = st.mode & os.S.IFMT;
335 switch (m) {
336 os.S.IFBLK => break :blk Kind.BlockDevice,
337 os.S.IFCHR => break :blk Kind.CharacterDevice,
338 os.S.IFDIR => break :blk Kind.Directory,
339 os.S.IFIFO => break :blk Kind.NamedPipe,
340 os.S.IFLNK => break :blk Kind.SymLink,
341 os.S.IFREG => break :blk Kind.File,
342 os.S.IFSOCK => break :blk Kind.UnixDomainSocket,
343 else => {},
344 }
345 if (builtin.os.tag == .solaris) switch (m) {
346 os.S.IFDOOR => break :blk Kind.Door,
347 os.S.IFPORT => break :blk Kind.EventPort,
348 else => {},
349 };
350
351 break :blk .Unknown;
352 };
353
323354 return Stat{
324355 .inode = st.ino,
325356 .size = @bitCast(u64, st.size),
326357 .mode = st.mode,
327 .kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) {
328 .BLOCK_DEVICE => Kind.BlockDevice,
329 .CHARACTER_DEVICE => Kind.CharacterDevice,
330 .DIRECTORY => Kind.Directory,
331 .SYMBOLIC_LINK => Kind.SymLink,
332 .REGULAR_FILE => Kind.File,
333 .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket,
334 else => Kind.Unknown,
335 } else switch (st.mode & os.S.IFMT) {
336 os.S.IFBLK => Kind.BlockDevice,
337 os.S.IFCHR => Kind.CharacterDevice,
338 os.S.IFDIR => Kind.Directory,
339 os.S.IFIFO => Kind.NamedPipe,
340 os.S.IFLNK => Kind.SymLink,
341 os.S.IFREG => Kind.File,
342 os.S.IFSOCK => Kind.UnixDomainSocket,
343 else => Kind.Unknown,
344 },
358 .kind = kind,
345359 .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
346360 .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
347361 .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
lib/std/fs/get_app_data_dir.zig+1-1
......@@ -44,7 +44,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
4444 };
4545 return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
4646 },
47 .linux, .freebsd, .netbsd, .dragonfly, .openbsd => {
47 .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
4848 const home_dir = os.getenv("HOME") orelse {
4949 // TODO look in /etc/passwd
5050 return error.AppDataDirUnavailable;
lib/std/fs/test.zig+1-1
......@@ -188,7 +188,7 @@ fn contains(entries: *const std.ArrayList(Dir.Entry), el: Dir.Entry) bool {
188188
189189test "Dir.realpath smoke test" {
190190 switch (builtin.os.tag) {
191 .linux, .windows, .macos, .ios, .watchos, .tvos => {},
191 .linux, .windows, .macos, .ios, .watchos, .tvos, .solaris => {},
192192 else => return error.SkipZigTest,
193193 }
194194
lib/std/os.zig+19
......@@ -31,6 +31,7 @@ pub const freebsd = std.c;
3131pub const haiku = std.c;
3232pub const netbsd = std.c;
3333pub const openbsd = std.c;
34pub const solaris = std.c;
3435pub const linux = @import("os/linux.zig");
3536pub const uefi = @import("os/uefi.zig");
3637pub const wasi = @import("os/wasi.zig");
......@@ -64,8 +65,10 @@ else switch (builtin.os.tag) {
6465};
6566
6667pub const AF = system.AF;
68pub const AF_SUN = system.AF_SUN;
6769pub const ARCH = system.ARCH;
6870pub const AT = system.AT;
71pub const AT_SUN = system.AT_SUN;
6972pub const CLOCK = system.CLOCK;
7073pub const CPU_COUNT = system.CPU_COUNT;
7174pub const CTL = system.CTL;
......@@ -101,6 +104,7 @@ pub const RR = system.RR;
101104pub const S = system.S;
102105pub const SA = system.SA;
103106pub const SC = system.SC;
107pub const _SC = system._SC;
104108pub const SEEK = system.SEEK;
105109pub const SHUT = system.SHUT;
106110pub const SIG = system.SIG;
......@@ -143,6 +147,10 @@ pub const off_t = system.off_t;
143147pub const oflags_t = system.oflags_t;
144148pub const pid_t = system.pid_t;
145149pub const pollfd = system.pollfd;
150pub const port_t = system.port_t;
151pub const port_event = system.port_event;
152pub const port_notify = system.port_notify;
153pub const file_obj = system.file_obj;
146154pub const rights_t = system.rights_t;
147155pub const rlim_t = system.rlim_t;
148156pub const rlimit = system.rlimit;
......@@ -2038,6 +2046,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr
20382046 .NOTDIR => return error.NotDir,
20392047 .NOMEM => return error.SystemResources,
20402048 .ROFS => return error.ReadOnlyFileSystem,
2049 .EXIST => return error.DirNotEmpty,
20412050 .NOTEMPTY => return error.DirNotEmpty,
20422051
20432052 .INVAL => unreachable, // invalid flags, or pathname has . as last component
......@@ -4667,6 +4676,16 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
46674676 };
46684677 return target;
46694678 },
4679 .solaris => {
4680 var procfs_buf: ["/proc/self/path/-2147483648".len:0]u8 = undefined;
4681 const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable;
4682
4683 const target = readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
4684 error.UnsupportedReparsePointType => unreachable,
4685 else => |e| return e,
4686 };
4687 return target;
4688 },
46704689 else => @compileError("querying for canonical path of a handle is unsupported on this host"),
46714690 }
46724691}
lib/std/os/test.zig+20-7
......@@ -188,7 +188,10 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
188188}
189189
190190test "link with relative paths" {
191 if (native_os != .linux) return error.SkipZigTest;
191 switch (native_os) {
192 .linux, .solaris => {},
193 else => return error.SkipZigTest,
194 }
192195 var cwd = fs.cwd();
193196
194197 cwd.deleteFile("example.txt") catch {};
......@@ -222,7 +225,10 @@ test "link with relative paths" {
222225}
223226
224227test "linkat with different directories" {
225 if (native_os != .linux) return error.SkipZigTest;
228 switch (native_os) {
229 .linux, .solaris => {},
230 else => return error.SkipZigTest,
231 }
226232 var cwd = fs.cwd();
227233 var tmp = tmpDir(.{});
228234
......@@ -634,8 +640,10 @@ test "fcntl" {
634640}
635641
636642test "signalfd" {
637 if (native_os != .linux)
638 return error.SkipZigTest;
643 switch (native_os) {
644 .linux, .solaris => {},
645 else => return error.SkipZigTest,
646 }
639647 _ = std.os.signalfd;
640648}
641649
......@@ -658,8 +666,10 @@ test "sync" {
658666}
659667
660668test "fsync" {
661 if (native_os != .linux and native_os != .windows)
662 return error.SkipZigTest;
669 switch (native_os) {
670 .linux, .windows, .solaris => {},
671 else => return error.SkipZigTest,
672 }
663673
664674 var tmp = tmpDir(.{});
665675 defer tmp.cleanup();
......@@ -754,7 +764,10 @@ test "sigaction" {
754764}
755765
756766test "dup & dup2" {
757 if (native_os != .linux) return error.SkipZigTest;
767 switch (native_os) {
768 .linux, .solaris => {},
769 else => return error.SkipZigTest,
770 }
758771
759772 var tmp = tmpDir(.{});
760773 defer tmp.cleanup();
lib/std/process.zig+2-1
......@@ -625,7 +625,7 @@ pub const UserInfo = struct {
625625/// POSIX function which gets a uid from username.
626626pub fn getUserInfo(name: []const u8) !UserInfo {
627627 return switch (builtin.os.tag) {
628 .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku => posixGetUserInfo(name),
628 .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku, .solaris => posixGetUserInfo(name),
629629 else => @compileError("Unsupported OS"),
630630 };
631631}
......@@ -753,6 +753,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
753753 .netbsd,
754754 .dragonfly,
755755 .openbsd,
756 .solaris,
756757 => {
757758 var paths = List.init(allocator);
758759 errdefer {
lib/std/target.zig+9-3
......@@ -235,7 +235,6 @@ pub const Target = struct {
235235 .fuchsia,
236236 .kfreebsd,
237237 .lv2,
238 .solaris,
239238 .zos,
240239 .haiku,
241240 .minix,
......@@ -310,6 +309,12 @@ pub const Target = struct {
310309 .max = .{ .major = 6, .minor = 0 },
311310 },
312311 },
312 .solaris => return .{
313 .semver = .{
314 .min = .{ .major = 5, .minor = 11 },
315 .max = .{ .major = 5, .minor = 11 },
316 },
317 },
313318
314319 .linux => return .{
315320 .linux = .{
......@@ -353,6 +358,7 @@ pub const Target = struct {
353358 .netbsd,
354359 .openbsd,
355360 .dragonfly,
361 .solaris,
356362 => return TaggedVersionRange{ .semver = self.version_range.semver },
357363
358364 else => return .none,
......@@ -385,6 +391,7 @@ pub const Target = struct {
385391 .dragonfly,
386392 .openbsd,
387393 .haiku,
394 .solaris,
388395 => true,
389396
390397 .linux,
......@@ -395,7 +402,6 @@ pub const Target = struct {
395402 .fuchsia,
396403 .kfreebsd,
397404 .lv2,
398 .solaris,
399405 .zos,
400406 .minix,
401407 .rtems,
......@@ -1516,6 +1522,7 @@ pub const Target = struct {
15161522 .netbsd => return copy(&result, "/libexec/ld.elf_so"),
15171523 .openbsd => return copy(&result, "/usr/libexec/ld.so"),
15181524 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
1525 .solaris => return copy(&result, "/lib/64/ld.so.1"),
15191526 .linux => switch (self.cpu.arch) {
15201527 .i386,
15211528 .sparc,
......@@ -1634,7 +1641,6 @@ pub const Target = struct {
16341641 .fuchsia,
16351642 .kfreebsd,
16361643 .lv2,
1637 .solaris,
16381644 .zos,
16391645 .minix,
16401646 .rtems,
lib/std/zig/system.zig+23
......@@ -101,6 +101,17 @@ pub const NativePaths = struct {
101101 return self;
102102 }
103103
104 if (comptime native_target.os.tag == .solaris) {
105 try self.addLibDir("/usr/lib/64");
106 try self.addLibDir("/usr/local/lib/64");
107 try self.addLibDir("/lib/64");
108
109 try self.addIncludeDir("/usr/include");
110 try self.addIncludeDir("/usr/local/include");
111
112 return self;
113 }
114
104115 if (native_target.os.tag != .windows) {
105116 const triple = try native_target.linuxTriple(allocator);
106117 const qual = native_target.cpu.arch.ptrBitWidth();
......@@ -243,6 +254,18 @@ pub const NativeTargetInfo = struct {
243254 error.InvalidVersion => {},
244255 }
245256 },
257 .solaris => {
258 const uts = std.os.uname();
259 const release = mem.spanZ(&uts.release);
260 if (std.builtin.Version.parse(release)) |ver| {
261 os.version_range.semver.min = ver;
262 os.version_range.semver.max = ver;
263 } else |err| switch (err) {
264 error.Overflow => {},
265 error.InvalidCharacter => {},
266 error.InvalidVersion => {},
267 }
268 },
246269 .windows => {
247270 const detected_version = windows.detectRuntimeVersion();
248271 os.version_range.windows.min = detected_version;
src/libc_installation.zig+1
......@@ -221,6 +221,7 @@ pub const LibCInstallation = struct {
221221 batch.add(&async self.findNativeIncludeDirPosix(args));
222222 switch (Target.current.os.tag) {
223223 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
224 .solaris => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib/64"),
224225 .linux => batch.add(&async self.findNativeCrtDirPosix(args)),
225226 else => {},
226227 }
src/link/Elf.zig+9
......@@ -3446,6 +3446,15 @@ const CsuObjects = struct {
34463446 .static_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
34473447 // zig fmt: on
34483448 },
3449 .solaris => switch (mode) {
3450 // zig fmt: off
3451 .dynamic_lib => result.set( null, "crti.o", null, null, "crtn.o" ),
3452 .dynamic_exe,
3453 .dynamic_pie => result.set( "crt1.o", "crti.o", null, null, "crtn.o" ),
3454 .static_exe,
3455 .static_pie => result.set( null, null, null, null, null ),
3456 // zig fmt: on
3457 },
34493458 else => {},
34503459 }
34513460 }
src/stage1/os.hpp+2
......@@ -33,6 +33,8 @@
3333#define ZIG_OS_OPENBSD
3434#elif defined(__HAIKU__)
3535#define ZIG_OS_HAIKU
36#elif defined(__sun)
37#define ZIG_OS_SOLARIS
3638#else
3739#define ZIG_OS_UNKNOWN
3840#endif
src/stage1/target.cpp+4-1
......@@ -399,6 +399,9 @@ Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
399399#elif defined(ZIG_OS_HAIKU)
400400 *out_os = OsHaiku;
401401 return ErrorNone;
402#elif defined(ZIG_OS_SOLARIS)
403 *out_os = OsSolaris;
404 return ErrorNone;
402405#else
403406 zig_panic("stage1 is unable to detect native target for this OS");
404407#endif
......@@ -670,6 +673,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
670673 case OsOpenBSD:
671674 case OsWASI:
672675 case OsHaiku:
676 case OsSolaris:
673677 case OsEmscripten:
674678 case OsPlan9:
675679 switch (id) {
......@@ -728,7 +732,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
728732 case OsCloudABI:
729733 case OsKFreeBSD:
730734 case OsLv2:
731 case OsSolaris:
732735 case OsZOS:
733736 case OsMinix:
734737 case OsRTEMS:
src/target.zig+7
......@@ -433,6 +433,13 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
433433 "-lc",
434434 "-lutil",
435435 },
436 .solaris => &[_][]const u8{
437 "-lm",
438 "-lsocket",
439 "-lnsl",
440 // Solaris releases after 10 merged the threading libraries into libc.
441 "-lc",
442 },
436443 .haiku => &[_][]const u8{
437444 "-lm",
438445 "-lroot",
src/type.zig+1-1
......@@ -3800,6 +3800,7 @@ pub const CType = enum {
38003800 .wasi,
38013801 .emscripten,
38023802 .plan9,
3803 .solaris,
38033804 => switch (self) {
38043805 .short,
38053806 .ushort,
......@@ -3851,7 +3852,6 @@ pub const CType = enum {
38513852 .fuchsia,
38523853 .kfreebsd,
38533854 .lv2,
3854 .solaris,
38553855 .zos,
38563856 .haiku,
38573857 .minix,