1//! This file provides the system interface functions for Linux matching those
2//! that are provided by libc, whether or not libc is linked. The following
3//! abstractions are made:
4//! * Implement all the syscalls in the same way that libc functions will
5//! provide `rename` when only the `renameat` syscall exists.
6const std = @import("../std.zig");
7const builtin = @import("builtin");
8const assert = std.debug.assert;
9const maxInt = std.math.maxInt;
10const elf = std.elf;
11const vdso = @import("linux/vdso.zig");
12const dl = @import("../dynamic_library.zig");
13const native_arch = builtin.cpu.arch;
14const native_abi = builtin.abi;
15const native_endian = native_arch.endian();
16const is_loongarch = native_arch.isLoongArch();
17const is_mips = native_arch.isMIPS();
18const is_ppc = native_arch.isPowerPC();
19const is_riscv = native_arch.isRISCV();
20const is_sparc = native_arch.isSPARC();
21const is_hppa = native_arch.isHppa();
22const iovec = std.posix.iovec;
23const iovec_const = std.posix.iovec_const;
24const winsize = std.posix.winsize;
25const ACCMODE = std.posix.ACCMODE;
26
27test {
28 if (builtin.os.tag == .linux) {
29 _ = @import("linux/test.zig");
30 }
31}
32
33const arch_bits = switch (native_arch) {
34 .aarch64, .aarch64_be => @import("linux/aarch64.zig"),
35 .alpha => @import("linux/alpha.zig"),
36 .arc, .arceb => @import("linux/arc.zig"),
37 .arm, .armeb, .thumb, .thumbeb => @import("linux/arm.zig"),
38 .csky => @import("linux/csky.zig"),
39 .hexagon => @import("linux/hexagon.zig"),
40 .loongarch32 => @import("linux/loongarch32.zig"),
41 .loongarch64 => @import("linux/loongarch64.zig"),
42 .m68k => @import("linux/m68k.zig"),
43 .microblaze, .microblazeel => @import("linux/microblaze.zig"),
44 .mips, .mipsel => @import("linux/mips.zig"),
45 .mips64, .mips64el => switch (builtin.abi) {
46 .gnuabin32, .muslabin32, .abin32 => @import("linux/mipsn32.zig"),
47 else => @import("linux/mips64.zig"),
48 },
49 .or1k => @import("linux/or1k.zig"),
50 .powerpc, .powerpcle => @import("linux/powerpc.zig"),
51 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
52 .riscv32 => @import("linux/riscv32.zig"),
53 .riscv64 => @import("linux/riscv64.zig"),
54 .s390x => @import("linux/s390x.zig"),
55 .sh, .sheb => @import("linux/sh.zig"),
56 .sparc => @import("linux/sparc.zig"),
57 .sparc64 => @import("linux/sparc64.zig"),
58 .x86 => @import("linux/x86.zig"),
59 .x86_64 => switch (builtin.abi) {
60 .gnux32, .muslx32, .x32 => @import("linux/x32.zig"),
61 else => @import("linux/x86_64.zig"),
62 },
63 .xtensa, .xtensaeb => @import("linux/xtensa.zig"),
64 else => struct {},
65};
66
67const syscall_bits = if (native_arch.isThumb()) @import("linux/thumb.zig") else arch_bits;
68
69pub const syscall_arg_t = syscall_bits.syscall_arg_t;
70pub const syscall0 = syscall_bits.syscall0;
71pub const syscall1 = syscall_bits.syscall1;
72pub const syscall2 = syscall_bits.syscall2;
73pub const syscall3 = syscall_bits.syscall3;
74pub const syscall4 = syscall_bits.syscall4;
75pub const syscall5 = syscall_bits.syscall5;
76pub const syscall6 = syscall_bits.syscall6;
77pub const syscall7 = syscall_bits.syscall7;
78pub const restore = syscall_bits.restore;
79pub const restore_rt = syscall_bits.restore_rt;
80pub const socketcall = syscall_bits.socketcall;
81pub const syscall_pipe = syscall_bits.syscall_pipe;
82pub const syscall_fork = syscall_bits.syscall_fork;
83pub const syscall_lseek = syscall_bits.syscall_lseek;
84
85pub fn clone(
86 func: *const fn (arg: usize) callconv(.c) u8,
87 stack: usize,
88 flags: u32,
89 arg: usize,
90 ptid: ?*pid_t,
91 tp: usize, // aka tls
92 ctid: ?*pid_t,
93) usize {
94 // Can't directly call a naked function; cast to C calling convention first.
95 return @as(*const fn (
96 *const fn (arg: usize) callconv(.c) u8,
97 usize,
98 u32,
99 usize,
100 ?*pid_t,
101 usize,
102 ?*pid_t,
103 ) callconv(.c) usize, @ptrCast(&syscall_bits.clone))(func, stack, flags, arg, ptid, tp, ctid);
104}
105
106pub const ARCH = arch_bits.ARCH;
107pub const SC = arch_bits.SC;
108pub const VDSO = arch_bits.VDSO;
109pub const user_desc = arch_bits.user_desc;
110
111pub const blkcnt_t = u64;
112pub const blksize_t = u32;
113pub const dev_t = u32;
114pub const ino_t = u64;
115pub const mode_t = u32;
116pub const nlink_t = u32;
117pub const off_t = i64;
118pub const pid_t = i32;
119pub const fd_t = i32;
120pub const socket_t = fd_t;
121pub const uid_t = u32;
122pub const gid_t = u32;
123pub const clock_t = isize;
124pub const time_t = arch_bits.time_t;
125
126pub const tls = @import("linux/tls.zig");
127pub const BPF = @import("linux/bpf.zig");
128pub const IOCTL = @import("linux/ioctl.zig");
129pub const SECCOMP = @import("linux/seccomp.zig");
130
131pub const syscalls = @import("linux/syscalls.zig");
132pub const SYS = switch (native_arch) {
133 .arc, .arceb => syscalls.Arc,
134 .aarch64, .aarch64_be => syscalls.Arm64,
135 .alpha => syscalls.Alpha,
136 .arm, .armeb, .thumb, .thumbeb => syscalls.Arm,
137 .csky => syscalls.CSky,
138 .hexagon => syscalls.Hexagon,
139 .hppa => syscalls.Hppa,
140 .hppa64 => syscalls.Hppa64,
141 .loongarch32 => syscalls.LoongArch32,
142 .loongarch64 => syscalls.LoongArch64,
143 .m68k => syscalls.M68k,
144 .microblaze, .microblazeel => syscalls.Microblaze,
145 .mips, .mipsel => syscalls.MipsO32,
146 .mips64, .mips64el => switch (builtin.abi) {
147 .gnuabin32, .muslabin32, .abin32 => syscalls.MipsN32,
148 else => syscalls.MipsN64,
149 },
150 .or1k => syscalls.OpenRisc,
151 .powerpc, .powerpcle => syscalls.PowerPC,
152 .powerpc64, .powerpc64le => syscalls.PowerPC64,
153 .riscv32 => syscalls.RiscV32,
154 .riscv64 => syscalls.RiscV64,
155 .s390x => syscalls.S390x,
156 .sh, .sheb => syscalls.Sh,
157 .sparc => syscalls.Sparc,
158 .sparc64 => syscalls.Sparc64,
159 .x86 => syscalls.X86,
160 .x86_64 => switch (builtin.abi) {
161 .gnux32, .muslx32, .x32 => syscalls.X32,
162 else => syscalls.X64,
163 },
164 .xtensa, .xtensaeb => syscalls.Xtensa,
165 else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),
166};
167
168pub const MAP_TYPE = enum(u4) {
169 SHARED = 0x01,
170 PRIVATE = 0x02,
171 SHARED_VALIDATE = 0x03,
172 DROPPABLE = 0x08,
173};
174
175pub const MAP = switch (native_arch) {
176 .x86_64, .x86 => packed struct(u32) {
177 TYPE: MAP_TYPE,
178 FIXED: bool = false,
179 ANONYMOUS: bool = false,
180 @"32BIT": bool = false,
181 _7: u1 = 0,
182 GROWSDOWN: bool = false,
183 _9: u2 = 0,
184 DENYWRITE: bool = false,
185 EXECUTABLE: bool = false,
186 LOCKED: bool = false,
187 NORESERVE: bool = false,
188 POPULATE: bool = false,
189 NONBLOCK: bool = false,
190 STACK: bool = false,
191 HUGETLB: bool = false,
192 SYNC: bool = false,
193 FIXED_NOREPLACE: bool = false,
194 _21: u5 = 0,
195 UNINITIALIZED: bool = false,
196 _: u5 = 0,
197 },
198 .aarch64, .aarch64_be, .arm, .armeb, .thumb, .thumbeb => packed struct(u32) {
199 TYPE: MAP_TYPE,
200 FIXED: bool = false,
201 ANONYMOUS: bool = false,
202 _6: u2 = 0,
203 GROWSDOWN: bool = false,
204 _9: u2 = 0,
205 DENYWRITE: bool = false,
206 EXECUTABLE: bool = false,
207 LOCKED: bool = false,
208 NORESERVE: bool = false,
209 POPULATE: bool = false,
210 NONBLOCK: bool = false,
211 STACK: bool = false,
212 HUGETLB: bool = false,
213 SYNC: bool = false,
214 FIXED_NOREPLACE: bool = false,
215 _21: u5 = 0,
216 UNINITIALIZED: bool = false,
217 _: u5 = 0,
218 },
219 .riscv32, .riscv64, .loongarch32, .loongarch64 => packed struct(u32) {
220 TYPE: MAP_TYPE,
221 FIXED: bool = false,
222 ANONYMOUS: bool = false,
223 _6: u9 = 0,
224 POPULATE: bool = false,
225 NONBLOCK: bool = false,
226 STACK: bool = false,
227 HUGETLB: bool = false,
228 SYNC: bool = false,
229 FIXED_NOREPLACE: bool = false,
230 _21: u5 = 0,
231 UNINITIALIZED: bool = false,
232 _: u5 = 0,
233 },
234 .sparc, .sparc64 => packed struct(u32) {
235 TYPE: MAP_TYPE,
236 FIXED: bool = false,
237 ANONYMOUS: bool = false,
238 NORESERVE: bool = false,
239 _7: u1 = 0,
240 LOCKED: bool = false,
241 GROWSDOWN: bool = false,
242 _10: u1 = 0,
243 DENYWRITE: bool = false,
244 EXECUTABLE: bool = false,
245 _13: u2 = 0,
246 POPULATE: bool = false,
247 NONBLOCK: bool = false,
248 STACK: bool = false,
249 HUGETLB: bool = false,
250 SYNC: bool = false,
251 FIXED_NOREPLACE: bool = false,
252 _21: u5 = 0,
253 UNINITIALIZED: bool = false,
254 _: u5 = 0,
255 },
256 .mips, .mipsel, .mips64, .mips64el => packed struct(u32) {
257 TYPE: MAP_TYPE,
258 FIXED: bool = false,
259 _5: u1 = 0,
260 @"32BIT": bool = false,
261 _7: u3 = 0,
262 NORESERVE: bool = false,
263 ANONYMOUS: bool = false,
264 GROWSDOWN: bool = false,
265 DENYWRITE: bool = false,
266 EXECUTABLE: bool = false,
267 LOCKED: bool = false,
268 POPULATE: bool = false,
269 NONBLOCK: bool = false,
270 STACK: bool = false,
271 HUGETLB: bool = false,
272 FIXED_NOREPLACE: bool = false,
273 _21: u5 = 0,
274 UNINITIALIZED: bool = false,
275 _: u5 = 0,
276 },
277 .powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) {
278 TYPE: MAP_TYPE,
279 FIXED: bool = false,
280 ANONYMOUS: bool = false,
281 NORESERVE: bool = false,
282 LOCKED: bool = false,
283 GROWSDOWN: bool = false,
284 _9: u2 = 0,
285 DENYWRITE: bool = false,
286 EXECUTABLE: bool = false,
287 _13: u2 = 0,
288 POPULATE: bool = false,
289 NONBLOCK: bool = false,
290 STACK: bool = false,
291 HUGETLB: bool = false,
292 SYNC: bool = false,
293 FIXED_NOREPLACE: bool = false,
294 _21: u5 = 0,
295 UNINITIALIZED: bool = false,
296 _: u5 = 0,
297 },
298 .arc,
299 .arceb,
300 .csky,
301 .hexagon,
302 .m68k,
303 .microblaze,
304 .microblazeel,
305 .or1k,
306 .s390x,
307 .sh,
308 .sheb,
309 => packed struct(u32) {
310 TYPE: MAP_TYPE,
311 FIXED: bool = false,
312 ANONYMOUS: bool = false,
313 _4: u1 = 0,
314 _5: u1 = 0,
315 GROWSDOWN: bool = false,
316 _7: u1 = 0,
317 _8: u1 = 0,
318 DENYWRITE: bool = false,
319 EXECUTABLE: bool = false,
320 LOCKED: bool = false,
321 NORESERVE: bool = false,
322 POPULATE: bool = false,
323 NONBLOCK: bool = false,
324 STACK: bool = false,
325 HUGETLB: bool = false,
326 SYNC: bool = false,
327 FIXED_NOREPLACE: bool = false,
328 _19: u5 = 0,
329 UNINITIALIZED: bool = false,
330 _: u5 = 0,
331 },
332 .alpha => packed struct(u32) {
333 TYPE: MAP_TYPE,
334 ANONYMOUS: bool = false,
335 _3: u1 = 0,
336 _4: u1 = 0,
337 _5: u1 = 0,
338 FIXED: bool = false,
339 _7: u1 = 0,
340 _8: u1 = 0,
341 _9: u1 = 0,
342 GROWSDOWN: bool = false,
343 DENYWRITE: bool = false,
344 EXECUTABLE: bool = false,
345 LOCKED: bool = false,
346 NORESERVE: bool = false,
347 POPULATE: bool = false,
348 NONBLOCK: bool = false,
349 STACK: bool = false,
350 HUGHETLB: bool = false,
351 FIXED_NOREPLACE: bool = false,
352 _19: u4 = 0,
353 _20: u1 = 0,
354 _: u5 = 0,
355 },
356 .xtensa, .xtensaeb => packed struct(u32) {
357 TYPE: MAP_TYPE,
358 FIXED: bool = false,
359 _RENAME: bool = false,
360 _AUTOGROW: bool = false,
361 _LOCAL: bool = false,
362 _AUTORSRV: bool = false,
363 _1: u1 = 0,
364 NORESERVE: bool = false,
365 ANONYMOUS: bool = false,
366 GROWSDOWN: bool = false,
367 DENYWRITE: bool = false,
368 EXECUTABLE: bool = false,
369 LOCKED: bool = false,
370 POPULATE: bool = false,
371 NONBLOCK: bool = false,
372 STACK: bool = false,
373 HUGETLB: bool = false,
374 FIXED_NOREPLACE: bool = false,
375 _2: u5 = 0,
376 UNINITIALIZED: bool = false,
377 _3: u5 = 0,
378 },
379 else => @compileError("missing std.os.linux.MAP constants for this architecture"),
380};
381
382pub const MREMAP = packed struct(u32) {
383 MAYMOVE: bool = false,
384 FIXED: bool = false,
385 DONTUNMAP: bool = false,
386 _: u29 = 0,
387};
388
389pub const O = switch (native_arch) {
390 .x86_64 => packed struct(u32) {
391 ACCMODE: ACCMODE = .RDONLY,
392 _2: u4 = 0,
393 CREAT: bool = false,
394 EXCL: bool = false,
395 NOCTTY: bool = false,
396 TRUNC: bool = false,
397 APPEND: bool = false,
398 NONBLOCK: bool = false,
399 DSYNC: bool = false,
400 ASYNC: bool = false,
401 DIRECT: bool = false,
402 _15: u1 = 0,
403 DIRECTORY: bool = false,
404 NOFOLLOW: bool = false,
405 NOATIME: bool = false,
406 CLOEXEC: bool = false,
407 SYNC: bool = false,
408 PATH: bool = false,
409 /// This is typically invalid without also setting `DIRECTORY`.
410 TMPFILE: bool = false,
411 _23: u9 = 0,
412 },
413 .x86, .riscv32, .riscv64, .loongarch32, .loongarch64 => packed struct(u32) {
414 ACCMODE: ACCMODE = .RDONLY,
415 _2: u4 = 0,
416 CREAT: bool = false,
417 EXCL: bool = false,
418 NOCTTY: bool = false,
419 TRUNC: bool = false,
420 APPEND: bool = false,
421 NONBLOCK: bool = false,
422 DSYNC: bool = false,
423 ASYNC: bool = false,
424 DIRECT: bool = false,
425 LARGEFILE: bool = false,
426 DIRECTORY: bool = false,
427 NOFOLLOW: bool = false,
428 NOATIME: bool = false,
429 CLOEXEC: bool = false,
430 SYNC: bool = false,
431 PATH: bool = false,
432 /// This is typically invalid without also setting `DIRECTORY`.
433 TMPFILE: bool = false,
434 _23: u9 = 0,
435 },
436 .aarch64, .aarch64_be, .arm, .armeb, .thumb, .thumbeb => packed struct(u32) {
437 ACCMODE: ACCMODE = .RDONLY,
438 _2: u4 = 0,
439 CREAT: bool = false,
440 EXCL: bool = false,
441 NOCTTY: bool = false,
442 TRUNC: bool = false,
443 APPEND: bool = false,
444 NONBLOCK: bool = false,
445 DSYNC: bool = false,
446 ASYNC: bool = false,
447 DIRECTORY: bool = false,
448 NOFOLLOW: bool = false,
449 DIRECT: bool = false,
450 LARGEFILE: bool = false,
451 NOATIME: bool = false,
452 CLOEXEC: bool = false,
453 SYNC: bool = false,
454 PATH: bool = false,
455 /// This is typically invalid without also setting `DIRECTORY`.
456 TMPFILE: bool = false,
457 _23: u9 = 0,
458 },
459 .sparc, .sparc64 => packed struct(u32) {
460 ACCMODE: ACCMODE = .RDONLY,
461 _2: u1 = 0,
462 APPEND: bool = false,
463 _4: u2 = 0,
464 ASYNC: bool = false,
465 _7: u2 = 0,
466 CREAT: bool = false,
467 TRUNC: bool = false,
468 EXCL: bool = false,
469 _12: u1 = 0,
470 DSYNC: bool = false,
471 NONBLOCK: bool = false,
472 NOCTTY: bool = false,
473 DIRECTORY: bool = false,
474 NOFOLLOW: bool = false,
475 _18: u2 = 0,
476 DIRECT: bool = false,
477 NOATIME: bool = false,
478 CLOEXEC: bool = false,
479 SYNC: bool = false,
480 PATH: bool = false,
481 /// This is typically invalid without also setting `DIRECTORY`.
482 TMPFILE: bool = false,
483 _27: u6 = 0,
484 },
485 .mips, .mipsel, .mips64, .mips64el => packed struct(u32) {
486 ACCMODE: ACCMODE = .RDONLY,
487 _2: u1 = 0,
488 APPEND: bool = false,
489 DSYNC: bool = false,
490 _5: u2 = 0,
491 NONBLOCK: bool = false,
492 CREAT: bool = false,
493 TRUNC: bool = false,
494 EXCL: bool = false,
495 NOCTTY: bool = false,
496 ASYNC: bool = false,
497 LARGEFILE: bool = false,
498 SYNC: bool = false,
499 DIRECT: bool = false,
500 DIRECTORY: bool = false,
501 NOFOLLOW: bool = false,
502 NOATIME: bool = false,
503 CLOEXEC: bool = false,
504 _20: u1 = 0,
505 PATH: bool = false,
506 /// This is typically invalid without also setting `DIRECTORY`.
507 TMPFILE: bool = false,
508 _23: u9 = 0,
509 },
510 .powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) {
511 ACCMODE: ACCMODE = .RDONLY,
512 _2: u4 = 0,
513 CREAT: bool = false,
514 EXCL: bool = false,
515 NOCTTY: bool = false,
516 TRUNC: bool = false,
517 APPEND: bool = false,
518 NONBLOCK: bool = false,
519 DSYNC: bool = false,
520 ASYNC: bool = false,
521 DIRECTORY: bool = false,
522 NOFOLLOW: bool = false,
523 LARGEFILE: bool = false,
524 DIRECT: bool = false,
525 NOATIME: bool = false,
526 CLOEXEC: bool = false,
527 SYNC: bool = false,
528 PATH: bool = false,
529 /// This is typically invalid without also setting `DIRECTORY`.
530 TMPFILE: bool = false,
531 _23: u9 = 0,
532 },
533 .arc,
534 .arceb,
535 .csky,
536 .hexagon,
537 .microblaze,
538 .microblazeel,
539 .or1k,
540 .s390x,
541 .sh,
542 .sheb,
543 .xtensa,
544 .xtensaeb,
545 => packed struct(u32) {
546 ACCMODE: ACCMODE = .RDONLY,
547 _2: u4 = 0,
548 CREAT: bool = false,
549 EXCL: bool = false,
550 NOCTTY: bool = false,
551 TRUNC: bool = false,
552 APPEND: bool = false,
553 NONBLOCK: bool = false,
554 DSYNC: bool = false,
555 ASYNC: bool = false,
556 DIRECT: bool = false,
557 LARGEFILE: bool = false,
558 DIRECTORY: bool = false,
559 NOFOLLOW: bool = false,
560 NOATIME: bool = false,
561 CLOEXEC: bool = false,
562 /// This is typically invalid without also setting `TMPFILE1` and `DIRECTORY`.
563 TMPFILE0: bool = false,
564 PATH: bool = false,
565 _22: u4 = 0,
566 /// This is typically invalid without also setting `TMPFILE0` and `DIRECTORY`.
567 TMPFILE1: bool = false,
568 _27: u5 = 0,
569
570 // #define O_RSYNC 04010000
571 // #define O_SYNC 04010000
572 // #define O_NDELAY O_NONBLOCK
573 },
574 .m68k => packed struct(u32) {
575 ACCMODE: ACCMODE = .RDONLY,
576 _2: u4 = 0,
577 CREAT: bool = false,
578 EXCL: bool = false,
579 NOCTTY: bool = false,
580 TRUNC: bool = false,
581 APPEND: bool = false,
582 NONBLOCK: bool = false,
583 DSYNC: bool = false,
584 ASYNC: bool = false,
585 DIRECTORY: bool = false,
586 NOFOLLOW: bool = false,
587 DIRECT: bool = false,
588 LARGEFILE: bool = false,
589 NOATIME: bool = false,
590 CLOEXEC: bool = false,
591 _20: u1 = 0,
592 PATH: bool = false,
593 _22: u10 = 0,
594 },
595 .alpha => packed struct(u32) {
596 ACCMODE: ACCMODE = .RDONLY,
597 NONBLOCK: bool = false,
598 APPEND: bool = false,
599 _4: u5 = 0,
600 CREAT: bool = false,
601 TRUNC: bool = false,
602 EXCL: bool = false,
603 NOCTTY: bool = false,
604 _9: u1 = 0,
605 DSYNC: bool = false,
606 DIRECTORY: bool = false,
607 NOFOLLOW: bool = false,
608 LARGEFILE: bool = false,
609 _14: u1 = 0,
610 DIRECT: bool = false,
611 NOATIME: bool = false,
612 CLOEXEC: bool = false,
613 SYNC: bool = false,
614 PATH: bool = false,
615 TMPFILE: bool = false,
616 _: u7 = 0,
617 },
618 else => @compileError("missing std.os.linux.O constants for this architecture"),
619};
620
621pub const HWCAP = switch (native_arch) {
622 .arm, .armeb, .thumb, .thumbeb => struct {
623 pub const SWP = 1 << 0;
624 pub const HALF = 1 << 1;
625 pub const THUMB = 1 << 2;
626 pub const @"26BIT" = 1 << 3;
627 pub const FAST_MULT = 1 << 4;
628 pub const FPA = 1 << 5;
629 pub const VFP = 1 << 6;
630 pub const EDSP = 1 << 7;
631 pub const JAVA = 1 << 8;
632 pub const IWMMXT = 1 << 9;
633 pub const CRUNCH = 1 << 10;
634 pub const THUMBEE = 1 << 11;
635 pub const NEON = 1 << 12;
636 pub const VFPv3 = 1 << 13;
637 pub const VFPv3D16 = 1 << 14;
638 pub const TLS = 1 << 15;
639 pub const VFPv4 = 1 << 16;
640 pub const IDIVA = 1 << 17;
641 pub const IDIVT = 1 << 18;
642 pub const VFPD32 = 1 << 19;
643 pub const IDIV = IDIVA | IDIVT;
644 pub const LPAE = 1 << 20;
645 pub const EVTSTRM = 1 << 21;
646 },
647 .loongarch32, .loongarch64 => struct {
648 pub const CPUCFG = 1 << 0;
649 pub const LAM = 1 << 1;
650 pub const UAL = 1 << 2;
651 pub const FPU = 1 << 3;
652 pub const LSX = 1 << 4;
653 pub const LASX = 1 << 5;
654 pub const CRC32 = 1 << 6;
655 pub const COMPLEX = 1 << 7;
656 pub const CRYPTO = 1 << 8;
657 pub const LVZ = 1 << 9;
658 pub const LBT_X86 = 1 << 10;
659 pub const LBT_ARM = 1 << 11;
660 pub const LBT_MIPS = 1 << 12;
661 pub const PTW = 1 << 13;
662 pub const LSPW = 1 << 14;
663 pub const SCQ = 1 << 15;
664 },
665 else => struct {},
666};
667
668pub const RENAME = packed struct(u32) {
669 /// Cannot be set together with `EXCHANGE`.
670 NOREPLACE: bool = false,
671 /// Cannot be set together with `NOREPLACE`.
672 EXCHANGE: bool = false,
673 WHITEOUT: bool = false,
674 _: u29 = 0,
675};
676
677/// Set by startup code, used by `getauxval`.
678pub var elf_aux_maybe: ?[*]std.elf.Auxv = null;
679
680/// Whether an external or internal getauxval implementation is used.
681const extern_getauxval = switch (builtin.zig_backend) {
682 // Calling extern functions is not yet supported with these backends
683 .stage2_arm,
684 .stage2_loongarch,
685 .stage2_powerpc,
686 .stage2_riscv64,
687 .stage2_sparc64,
688 => false,
689 else => !builtin.link_libc,
690};
691
692pub const getauxval = if (extern_getauxval) struct {
693 comptime {
694 const root = @import("root");
695 // Export this only when building an executable, otherwise it is overriding
696 // the libc implementation
697 if (builtin.output_mode == .Exe or @hasDecl(root, "main")) {
698 @export(&getauxvalImpl, .{ .name = "getauxval", .linkage = .weak });
699 }
700 }
701 extern fn getauxval(index: usize) usize;
702}.getauxval else getauxvalImpl;
703
704fn getauxvalImpl(index: usize) callconv(.c) usize {
705 @disableInstrumentation();
706 const auxv = elf_aux_maybe orelse return 0;
707 var i: usize = 0;
708 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
709 if (auxv[i].a_type == index)
710 return auxv[i].a_un.a_val;
711 }
712 return 0;
713}
714
715// Some architectures (and some syscalls) require 64bit parameters to be passed
716// in a even-aligned register pair.
717const require_aligned_register_pair =
718 builtin.cpu.arch.isArm() or
719 builtin.cpu.arch == .csky or
720 builtin.cpu.arch == .hexagon or
721 builtin.cpu.arch.isMIPS32() or
722 builtin.cpu.arch.isPowerPC32() or
723 builtin.cpu.arch.isXtensa();
724
725// Split a 64bit value into a {LSB,MSB} pair.
726// The LE/BE variants specify the endianness to assume.
727fn splitValueLE64(val: i64) [2]u32 {
728 const u: u64 = @bitCast(val);
729 return [2]u32{
730 @as(u32, @truncate(u)),
731 @as(u32, @truncate(u >> 32)),
732 };
733}
734fn splitValueBE64(val: i64) [2]u32 {
735 const u: u64 = @bitCast(val);
736 return [2]u32{
737 @as(u32, @truncate(u >> 32)),
738 @as(u32, @truncate(u)),
739 };
740}
741fn splitValue64(val: i64) [2]u32 {
742 const u: u64 = @bitCast(val);
743 switch (native_endian) {
744 .little => return [2]u32{
745 @as(u32, @truncate(u)),
746 @as(u32, @truncate(u >> 32)),
747 },
748 .big => return [2]u32{
749 @as(u32, @truncate(u >> 32)),
750 @as(u32, @truncate(u)),
751 },
752 }
753}
754
755/// Get the errno from a syscall return value. SUCCESS means no error.
756pub fn errno(r: u64) E {
757 const signed_r: i32 = @bitCast(@as(u32, @truncate(r)));
758 const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
759 return @fromBackingInt(@intCast(int));
760}
761
762pub fn brk(addr: usize) usize {
763 return syscall1(.brk, addr);
764}
765
766pub fn dup(old: fd_t) usize {
767 return syscall1(.dup, @as(u32, @bitCast(old)));
768}
769
770pub fn dup2(old: fd_t, new: fd_t) usize {
771 if (@hasField(SYS, "dup2")) {
772 return syscall2(.dup2, @as(u32, @bitCast(old)), @as(u32, @bitCast(new)));
773 } else {
774 if (old == new) {
775 if (std.debug.runtime_safety) {
776 const rc = fcntl(F.GETFD, @as(fd_t, old), 0);
777 if (@as(isize, @bitCast(rc)) < 0) return rc;
778 }
779 return @as(usize, @intCast(old));
780 } else {
781 return syscall3(.dup3, @as(u32, @bitCast(old)), @as(u32, @bitCast(new)), 0);
782 }
783 }
784}
785
786pub fn dup3(old: fd_t, new: fd_t, flags: u32) usize {
787 return syscall3(.dup3, @as(u32, @bitCast(old)), @as(u32, @bitCast(new)), flags);
788}
789
790pub fn chdir(path: [*:0]const u8) usize {
791 return syscall1(.chdir, @intFromPtr(path));
792}
793
794pub fn fchdir(fd: fd_t) usize {
795 return syscall1(.fchdir, @as(u32, @bitCast(fd)));
796}
797
798pub fn chroot(path: [*:0]const u8) usize {
799 return syscall1(.chroot, @intFromPtr(path));
800}
801
802pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) usize {
803 return syscall3(.execve, @intFromPtr(path), @intFromPtr(argv), @intFromPtr(envp));
804}
805
806pub const EXECVEAT = packed struct(u32) {
807 _1: u8 = 0, // 0x00000001
808 /// Do not follow symbolic links.
809 SYMLINK_NOFOLLOW: bool, // 0x00000100
810 _200: u3 = 0, // 0x00000200
811 /// Allow empty relative pathname.
812 EMPTY_PATH: bool, // 0x00001000
813 _: u19 = 0,
814};
815
816pub fn execveat(dirfd: fd_t, path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8, flags: EXECVEAT) usize {
817 return syscall5(.execveat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), @intFromPtr(argv), @intFromPtr(envp), @as(u32, @bitCast(flags)));
818}
819
820pub fn fork() usize {
821 if (comptime native_arch.isSPARC()) {
822 return syscall_fork();
823 } else if (@hasField(SYS, "fork")) {
824 return syscall0(.fork);
825 } else {
826 return syscall2(.clone, @backingInt(SIG.CHLD), 0);
827 }
828}
829
830pub fn futimens(fd: fd_t, times: ?*const [2]timespec) usize {
831 return utimensat(fd, null, times, 0);
832}
833
834pub fn utimensat(dirfd: fd_t, path: ?[*:0]const u8, times: ?*const [2]timespec, flags: u32) usize {
835 return syscall4(
836 if (@hasField(SYS, "utimensat") and native_arch != .hexagon) .utimensat else .utimensat_time64,
837 @as(u32, @bitCast(dirfd)),
838 @intFromPtr(path),
839 @intFromPtr(times),
840 flags,
841 );
842}
843
844pub fn fallocate(fd: fd_t, mode: mode_t, offset: off_t, length: off_t) usize {
845 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
846 const offset_halves = splitValue64(offset);
847 const length_halves = splitValue64(length);
848 return syscall6(
849 .fallocate,
850 @as(u32, @bitCast(fd)),
851 mode,
852 offset_halves[0],
853 offset_halves[1],
854 length_halves[0],
855 length_halves[1],
856 );
857 } else {
858 return syscall4(
859 .fallocate,
860 @as(u32, @bitCast(fd)),
861 mode,
862 @as(u64, @bitCast(offset)),
863 @as(u64, @bitCast(length)),
864 );
865 }
866}
867
868// The 4th parameter to the v1 futex syscall can either be an optional
869// pointer to a timespec, or a uint32, depending on which "op" is being
870// performed.
871pub const futex_param4 = extern union {
872 timeout: ?*const timespec,
873 /// On all platforms only the bottom 32-bits of `val2` are relevant.
874 /// This is 64-bit to match the pointer in the union.
875 val2: usize,
876};
877
878/// The futex v1 syscall, see also the newer the futex2_{wait,wakeup,requeue,waitv} syscalls.
879///
880/// The futex_op parameter is a sub-command and flags. The sub-command
881/// defines which of the subsequent paramters are relevant.
882pub fn futex(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, val2timeout: futex_param4, uaddr2: ?*const anyopaque, val3: u32) usize {
883 return syscall6(
884 if (@hasField(SYS, "futex") and native_arch != .hexagon) .futex else .futex_time64,
885 @intFromPtr(uaddr),
886 @as(u32, @bitCast(futex_op)),
887 val,
888 @intFromPtr(val2timeout.timeout),
889 @intFromPtr(uaddr2),
890 val3,
891 );
892}
893
894/// Three-argument variation of the v1 futex call. Only suitable for a
895/// futex_op that ignores the remaining arguments (e.g., FUTUX_OP.WAKE).
896pub fn futex_3arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32) usize {
897 return syscall3(
898 if (@hasField(SYS, "futex") and native_arch != .hexagon) .futex else .futex_time64,
899 @intFromPtr(uaddr),
900 @as(u32, @bitCast(futex_op)),
901 val,
902 );
903}
904
905/// Four-argument variation on the v1 futex call. Only suitable for
906/// futex_op that ignores the remaining arguments (e.g., FUTEX_OP.WAIT).
907pub fn futex_4arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, timeout: ?*const timespec) usize {
908 return syscall4(
909 if (@hasField(SYS, "futex") and native_arch != .hexagon) .futex else .futex_time64,
910 @intFromPtr(uaddr),
911 @as(u32, @bitCast(futex_op)),
912 val,
913 @intFromPtr(timeout),
914 );
915}
916
917/// Given an array of `futex2_waitone`, wait on each uaddr.
918/// The thread wakes if a futex_wake() is performed at any uaddr.
919/// The syscall returns immediately if any futex has *uaddr != val.
920/// timeout is an optional, absolute timeout value for the operation.
921/// The `flags` argument is for future use and currently should be `.{}`.
922/// Flags for private futexes, sizes, etc. should be set on the
923/// individual flags of each `futex2_waitone`.
924///
925/// Returns the array index of one of the woken futexes.
926/// No further information is provided: any number of other futexes may also
927/// have been woken by the same event, and if more than one futex was woken,
928/// the returned index may refer to any one of them.
929/// (It is not necessaryily the futex with the smallest index, nor the one
930/// most recently woken, nor...)
931///
932/// Requires at least kernel v5.16.
933pub fn futex2_waitv(
934 futexes: [*]const futex2_waitone,
935 /// Length of `futexes`. Max of FUTEX2_WAITONE_MAX.
936 nr_futexes: u32,
937 flags: FUTEX2_FLAGS_WAITV,
938 /// Optional absolute timeout. Always 64-bit, even on 32-bit platforms.
939 timeout: ?*const kernel_timespec,
940 /// Clock to be used for the timeout, realtime or monotonic.
941 clockid: clockid_t,
942) usize {
943 return syscall5(
944 .futex_waitv,
945 @intFromPtr(futexes),
946 nr_futexes,
947 @as(u32, @bitCast(flags)),
948 @intFromPtr(timeout),
949 @backingInt(clockid),
950 );
951}
952
953/// Wait on a single futex.
954/// Identical to the futex v1 `FUTEX.FUTEX_WAIT_BITSET` op, except it is part of the
955/// futex2 family of calls.
956///
957/// Requires at least kernel v6.7.
958pub fn futex2_wait(
959 /// Address of the futex to wait on.
960 uaddr: *const anyopaque,
961 /// Value of `uaddr`.
962 val: usize,
963 /// Bitmask to match against incoming wakeup masks. Must not be zero.
964 mask: usize,
965 flags: FUTEX2_FLAGS,
966 /// Optional absolute timeout. Always 64-bit, even on 32-bit platforms.
967 timeout: ?*const kernel_timespec,
968 /// Clock to be used for the timeout, realtime or monotonic.
969 clockid: clockid_t,
970) usize {
971 return syscall6(
972 .futex_wait,
973 @intFromPtr(uaddr),
974 val,
975 mask,
976 @as(u32, @bitCast(flags)),
977 @intFromPtr(timeout),
978 @backingInt(clockid),
979 );
980}
981
982/// Wake (subset of) waiters on given futex.
983/// Identical to the traditional `FUTEX.FUTEX_WAKE_BITSET` op, except it is part of the
984/// futex2 family of calls.
985///
986/// Requires at least kernel v6.7.
987pub fn futex2_wake(
988 /// Futex to wake
989 uaddr: *const anyopaque,
990 /// Bitmask to match against waiters.
991 mask: usize,
992 /// Maximum number of waiters on the futex to wake.
993 nr_wake: i32,
994 flags: FUTEX2_FLAGS,
995) usize {
996 return syscall4(
997 .futex_wake,
998 @intFromPtr(uaddr),
999 mask,
1000 @as(u32, @bitCast(nr_wake)),
1001 @as(u32, @bitCast(flags)),
1002 );
1003}
1004
1005/// Wake and/or requeue waiter(s) from one futex to another.
1006/// Identical to `FUTEX.CMP_REQUEUE`, except it is part of the futex2 family of calls.
1007///
1008/// Requires at least kernel v6.7.
1009pub fn futex2_requeue(
1010 /// The source and destination futexes. Must be a 2-element array.
1011 waiters: [*]const futex2_waitone,
1012 /// Currently unused.
1013 flags: FUTEX2_FLAGS_REQUEUE,
1014 /// Maximum number of waiters to wake on the source futex.
1015 nr_wake: i32,
1016 /// Maximum number of waiters to transfer to the destination futex.
1017 nr_requeue: i32,
1018) usize {
1019 return syscall4(
1020 .futex_requeue,
1021 @intFromPtr(waiters),
1022 @as(u32, @bitCast(flags)),
1023 @as(u32, @bitCast(nr_wake)),
1024 @as(u32, @bitCast(nr_requeue)),
1025 );
1026}
1027
1028pub fn getcwd(buf: [*]u8, size: usize) usize {
1029 return syscall2(.getcwd, @intFromPtr(buf), size);
1030}
1031
1032pub fn getdents(fd: fd_t, dirp: [*]u8, len: c_uint) usize {
1033 return syscall3(
1034 .getdents,
1035 @as(u32, @bitCast(fd)),
1036 @intFromPtr(dirp),
1037 len,
1038 );
1039}
1040
1041pub fn getdents64(fd: fd_t, dirp: [*]u8, len: c_uint) usize {
1042 return syscall3(
1043 .getdents64,
1044 @as(u32, @bitCast(fd)),
1045 @intFromPtr(dirp),
1046 len,
1047 );
1048}
1049
1050pub fn inotify_init1(flags: u32) usize {
1051 return syscall1(.inotify_init1, flags);
1052}
1053
1054pub fn inotify_add_watch(fd: fd_t, pathname: [*:0]const u8, mask: u32) usize {
1055 return syscall3(.inotify_add_watch, @as(u32, @bitCast(fd)), @intFromPtr(pathname), mask);
1056}
1057
1058pub fn inotify_rm_watch(fd: fd_t, wd: fd_t) usize {
1059 return syscall2(.inotify_rm_watch, @as(u32, @bitCast(fd)), @as(u32, @bitCast(wd)));
1060}
1061
1062pub fn fanotify_init(flags: fanotify.InitFlags, event_f_flags: u32) usize {
1063 return syscall2(.fanotify_init, @as(u32, @bitCast(flags)), event_f_flags);
1064}
1065
1066pub fn fanotify_mark(
1067 fd: fd_t,
1068 flags: fanotify.MarkFlags,
1069 mask: fanotify.MarkMask,
1070 dirfd: fd_t,
1071 pathname: ?[*:0]const u8,
1072) usize {
1073 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
1074 const mask_halves = splitValue64(@bitCast(mask));
1075 return syscall6(
1076 .fanotify_mark,
1077 @as(u32, @bitCast(fd)),
1078 @as(u32, @bitCast(flags)),
1079 mask_halves[0],
1080 mask_halves[1],
1081 @as(u32, @bitCast(dirfd)),
1082 @intFromPtr(pathname),
1083 );
1084 } else {
1085 return syscall5(
1086 .fanotify_mark,
1087 @as(u32, @bitCast(fd)),
1088 @as(u32, @bitCast(flags)),
1089 @as(u64, @bitCast(mask)),
1090 @as(u32, @bitCast(dirfd)),
1091 @intFromPtr(pathname),
1092 );
1093 }
1094}
1095
1096pub fn name_to_handle_at(
1097 dirfd: fd_t,
1098 pathname: [*:0]const u8,
1099 handle: *file_handle,
1100 mount_id: *i32,
1101 flags: u32,
1102) usize {
1103 return syscall5(
1104 .name_to_handle_at,
1105 @as(u32, @bitCast(dirfd)),
1106 @intFromPtr(pathname),
1107 @intFromPtr(handle),
1108 @intFromPtr(mount_id),
1109 flags,
1110 );
1111}
1112
1113pub fn readlink(noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
1114 if (@hasField(SYS, "readlink")) {
1115 return syscall3(.readlink, @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
1116 } else {
1117 return syscall4(.readlinkat, @as(u32, @bitCast(@as(i32, AT.FDCWD))), @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
1118 }
1119}
1120
1121pub fn readlinkat(dirfd: fd_t, noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
1122 return syscall4(.readlinkat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
1123}
1124
1125pub fn mkdir(path: [*:0]const u8, mode: mode_t) usize {
1126 if (@hasField(SYS, "mkdir")) {
1127 return syscall2(.mkdir, @intFromPtr(path), mode);
1128 } else {
1129 return syscall3(.mkdirat, @as(u32, @bitCast(@as(i32, AT.FDCWD))), @intFromPtr(path), mode);
1130 }
1131}
1132
1133pub fn mkdirat(dirfd: fd_t, path: [*:0]const u8, mode: mode_t) usize {
1134 return syscall3(.mkdirat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), mode);
1135}
1136
1137pub fn mknod(path: [*:0]const u8, mode: mode_t, dev: dev_t) usize {
1138 if (@hasField(SYS, "mknod")) {
1139 return syscall3(.mknod, @intFromPtr(path), mode, dev);
1140 } else {
1141 return mknodat(AT.FDCWD, path, mode, dev);
1142 }
1143}
1144
1145pub fn mknodat(dirfd: fd_t, path: [*:0]const u8, mode: mode_t, dev: dev_t) usize {
1146 return syscall4(.mknodat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), mode, dev);
1147}
1148
1149pub fn mount(special: ?[*:0]const u8, dir: [*:0]const u8, fstype: ?[*:0]const u8, flags: u32, data: usize) usize {
1150 return syscall5(.mount, @intFromPtr(special), @intFromPtr(dir), @intFromPtr(fstype), flags, data);
1151}
1152
1153pub fn umount(special: [*:0]const u8) usize {
1154 return syscall2(.umount2, @intFromPtr(special), 0);
1155}
1156
1157pub fn umount2(special: [*:0]const u8, flags: u32) usize {
1158 return syscall2(.umount2, @intFromPtr(special), flags);
1159}
1160
1161pub const MOVE_MOUNT = packed struct(u32) {
1162 /// Follow symlinks on from path.
1163 F_SYMLINKS: bool, // 0x00000001
1164 /// Follow automounts on from path.
1165 F_AUTOMOUNTS: bool, // 0x00000002
1166 /// Empty from path permitted.
1167 F_EMPTY_PATH: bool, // 0x00000004
1168 _8: bool = false, // 0x00000008
1169 /// Follow symlinks on to path.
1170 T_SYMLINKS: bool, // 0x00000010
1171 /// Follow automounts on to path.
1172 T_AUTOMOUNTS: bool, // 0x00000020
1173 /// Empty to path permitted.
1174 T_EMPTY_PATH: bool, // 0x00000040
1175 _80: bool = false, // 0x00000080
1176 /// Set sharing group instead.
1177 SET_GROUP: bool, // 0x00000100
1178 _: u23 = 0,
1179};
1180
1181pub fn move_mount(from_dirfd: fd_t, from_path: [*:0]const u8, to_dirfd: fd_t, to_path: [*:0]const u8, flags: MOVE_MOUNT) usize {
1182 return syscall5(
1183 .move_mount,
1184 @as(u32, @bitCast(from_dirfd)),
1185 @intFromPtr(from_path),
1186 @as(u32, @bitCast(to_dirfd)),
1187 @intFromPtr(to_path),
1188 @as(u32, @bitCast(flags)),
1189 );
1190}
1191
1192pub const MOUNT_ATTR = packed struct(u32) {
1193 /// Update atime relative to mtime/ctime.
1194 RELATIME: u0, // This is the default ATIME, it's true unless a different ATIME is set.
1195 /// Mount read-only.
1196 RDONLY: bool, // 0x00000001
1197 /// Ignore suid and sgid bits.
1198 NOSUID: bool, // 0x00000002
1199 /// Disallow access to device special files.
1200 NODEV: bool, // 0x00000004
1201 /// Disallow program execution.
1202 NOEXEC: bool, // 0x00000008
1203 /// Do not update access times.
1204 NOATIME: bool, // 0x00000010
1205 /// Always perform atime updates.
1206 STRICTATIME: bool, // 0x00000020
1207 _40: bool = false, // 0x00000040
1208 /// Do not update directory access times.
1209 NODIRATIME: bool, // 0x00000080
1210 _100: u12 = 0, // 0x00000100
1211 /// Idmap mount to @userns_fd in struct mount_attr.
1212 IDMAP: bool, // 0x00100000
1213 /// Do not follow symlinks.
1214 NOSYMFOLLOW: bool, // 0x00200000
1215 _: u10 = 0,
1216
1217 // ATIME: u32, // 0x00000070 This is a mask, not a flag.
1218};
1219
1220pub fn mount_setattr(dirfd: fd_t, path: [*:0]const u8, flags: MOUNT_ATTR) usize {
1221 return syscall3(.mount_setattr, @as(u32, @bitCast(dirfd)), @intFromPtr(path), @as(u32, @bitCast(flags)));
1222}
1223
1224pub const FSOPEN = packed struct(u32) {
1225 /// Set CLOEXEC on the new fd.
1226 CLOEXEC: bool, // 0x00000001
1227 _: u31 = 0,
1228};
1229
1230pub fn fsopen(fsname: [*:0]const u8, flags: FSOPEN) usize {
1231 return syscall2(.fsopen, @intFromPtr(fsname), @as(u32, @bitCast(flags)));
1232}
1233
1234pub const FSCONFIG_CMD = enum(u32) {
1235 /// Set parameter, supplying no value.
1236 SET_FLAG,
1237 /// Set parameter, supplying a string value.
1238 SET_STRING,
1239 /// Set parameter, supplying a binary blob value.
1240 SET_BINARY,
1241 /// Set parameter, supplying an object by path.
1242 SET_PATH,
1243 /// Set parameter, supplying an object by (empty) path.
1244 SET_PATH_EMPTY,
1245 /// Set parameter, supplying an object by fd.
1246 SET_FD,
1247 /// Invoke superblock creation.
1248 CREATE,
1249 /// Invoke superblock reconfiguration.
1250 RECONFIGURE,
1251};
1252
1253pub fn fsconfig(fd: fd_t, cmd: FSCONFIG_CMD, key: ?[*:0]const u8, value: ?[*:0]const u8, aux: u32) usize {
1254 return syscall5(.fsconfig, @as(u32, @bitCast(fd)), @backingInt(cmd), @intFromPtr(key), @intFromPtr(value), aux);
1255}
1256
1257pub const FSMOUNT = packed struct(u32) {
1258 /// Set CLOEXEC on the fd.
1259 CLOEXEC: bool, // 0x00000001
1260 _31: u31 = 0,
1261};
1262
1263pub fn fsmount(fsfd: fd_t, flags: FSMOUNT, attr_flags: MOUNT_ATTR) usize {
1264 return syscall3(.fsmount, @as(u32, @bitCast(fsfd)), @as(u32, @bitCast(flags)), @as(u32, @bitCast(attr_flags)));
1265}
1266
1267pub const FSPICK = packed struct(u32) {
1268 /// Set CLOEXEC on the new fd.
1269 CLOEXEC: bool, // 0x00000001
1270 SYMLINK_NOFOLLOW: bool, // 0x00000002
1271 NO_AUTOMOUNT: bool, // 0x00000004
1272 EMPTY_PATH: bool, // 0x00000008
1273 _28: u28 = 0,
1274};
1275
1276pub fn fspick(dirfd: fd_t, path: [*:0]const u8, flags: FSPICK) usize {
1277 return syscall3(.fspick, @as(u32, @bitCast(dirfd)), @intFromPtr(path), @as(u32, @bitCast(flags)));
1278}
1279
1280pub fn pivot_root(new_root: [*:0]const u8, put_old: [*:0]const u8) usize {
1281 return syscall2(.pivot_root, @intFromPtr(new_root), @intFromPtr(put_old));
1282}
1283
1284fn mmap2Unit() u64 {
1285 return switch (native_arch) {
1286 .arc, .arceb, .m68k => std.heap.pageSize(),
1287 .or1k => 8 << 10,
1288 else => 4 << 10,
1289 };
1290}
1291
1292pub fn mmap(address: ?[*]u8, length: usize, prot: PROT, flags: MAP, fd: fd_t, offset: off_t) usize {
1293 if (@hasField(SYS, "mmap2")) {
1294 return syscall6(
1295 .mmap2,
1296 @intFromPtr(address),
1297 length,
1298 @as(u32, @bitCast(prot)),
1299 @as(u32, @bitCast(flags)),
1300 @as(u32, @bitCast(fd)),
1301 @truncate(@as(u64, @bitCast(offset)) / mmap2Unit()),
1302 );
1303 } else {
1304 // The s390x mmap() syscall existed before Linux supported syscalls with 5+ parameters, so
1305 // it takes a single pointer to an array of arguments instead.
1306 return if (native_arch == .s390x) syscall1(
1307 .mmap,
1308 @intFromPtr(&[_]usize{
1309 @intFromPtr(address),
1310 length,
1311 @as(u32, @bitCast(prot)),
1312 @as(u32, @bitCast(flags)),
1313 @as(u32, @bitCast(fd)),
1314 @as(u64, @bitCast(offset)),
1315 }),
1316 ) else syscall6(
1317 .mmap,
1318 @intFromPtr(address),
1319 length,
1320 @as(u32, @bitCast(prot)),
1321 @as(u32, @bitCast(flags)),
1322 @as(u32, @bitCast(fd)),
1323 @as(u64, @bitCast(offset)),
1324 );
1325 }
1326}
1327
1328pub fn mprotect(address: [*]const u8, length: usize, protection: PROT) usize {
1329 return syscall3(.mprotect, @intFromPtr(address), length, @as(u32, @bitCast(protection)));
1330}
1331
1332pub fn mremap(old_addr: ?[*]const u8, old_len: usize, new_len: usize, flags: MREMAP, new_addr: ?[*]const u8) usize {
1333 return syscall5(
1334 .mremap,
1335 @intFromPtr(old_addr),
1336 old_len,
1337 new_len,
1338 @as(u32, @bitCast(flags)),
1339 @intFromPtr(new_addr),
1340 );
1341}
1342
1343pub const MSF = struct {
1344 pub const ASYNC = 1;
1345 pub const INVALIDATE = 2;
1346 pub const SYNC = 4;
1347};
1348
1349/// Can only be called on 64 bit systems.
1350pub fn mseal(address: [*]const u8, length: usize, flags: usize) usize {
1351 return syscall3(.mseal, @intFromPtr(address), length, flags);
1352}
1353
1354pub fn msync(address: [*]const u8, length: usize, flags: i32) usize {
1355 return syscall3(.msync, @intFromPtr(address), length, @as(u32, @bitCast(flags)));
1356}
1357
1358pub fn munmap(address: [*]const u8, length: usize) usize {
1359 return syscall2(.munmap, @intFromPtr(address), length);
1360}
1361
1362pub fn mlock(address: [*]const u8, length: usize) usize {
1363 return syscall2(.mlock, @intFromPtr(address), length);
1364}
1365
1366pub fn munlock(address: [*]const u8, length: usize) usize {
1367 return syscall2(.munlock, @intFromPtr(address), length);
1368}
1369
1370pub const MLOCK = packed struct(u32) {
1371 ONFAULT: bool = false,
1372 _1: u31 = 0,
1373};
1374
1375pub fn mlock2(address: [*]const u8, length: usize, flags: MLOCK) usize {
1376 return syscall3(.mlock2, @intFromPtr(address), length, @as(u32, @bitCast(flags)));
1377}
1378
1379pub const MCL = if (native_arch.isSPARC() or native_arch.isPowerPC()) packed struct(u32) {
1380 _0: u13 = 0,
1381 CURRENT: bool = false,
1382 FUTURE: bool = false,
1383 ONFAULT: bool = false,
1384 _4: u16 = 0,
1385} else packed struct(u32) {
1386 CURRENT: bool = false,
1387 FUTURE: bool = false,
1388 ONFAULT: bool = false,
1389 _3: u29 = 0,
1390};
1391
1392pub fn mlockall(flags: MCL) usize {
1393 return syscall1(.mlockall, @as(u32, @bitCast(flags)));
1394}
1395
1396pub fn munlockall() usize {
1397 return syscall0(.munlockall);
1398}
1399
1400pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
1401 if (@hasField(SYS, "poll")) {
1402 return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)));
1403 } else {
1404 var ts: timespec = if (timeout >= 0)
1405 .{
1406 .sec = @divTrunc(timeout, 1000),
1407 .nsec = @rem(timeout, 1000) * 1000000,
1408 }
1409 else
1410 undefined;
1411 return ppoll(
1412 fds,
1413 n,
1414 if (timeout >= 0) &ts else null,
1415 null,
1416 );
1417 }
1418}
1419
1420pub fn ppoll(fds: [*]pollfd, n: nfds_t, timeout: ?*timespec, sigmask: ?*const sigset_t) usize {
1421 return syscall5(
1422 if (@hasField(SYS, "ppoll") and native_arch != .hexagon) .ppoll else .ppoll_time64,
1423 @intFromPtr(fds),
1424 n,
1425 @intFromPtr(timeout),
1426 @intFromPtr(sigmask),
1427 NSIG / 8,
1428 );
1429}
1430
1431pub fn read(fd: fd_t, buf: [*]u8, count: usize) usize {
1432 return syscall3(.read, @as(u32, @bitCast(fd)), @intFromPtr(buf), count);
1433}
1434
1435pub fn pread(fd: fd_t, buf: [*]u8, count: usize, offset: off_t) usize {
1436 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
1437 const offset_halves = splitValue64(offset);
1438 if (require_aligned_register_pair) {
1439 return syscall6(
1440 .pread64,
1441 @as(u32, @bitCast(fd)),
1442 @intFromPtr(buf),
1443 count,
1444 0,
1445 offset_halves[0],
1446 offset_halves[1],
1447 );
1448 } else {
1449 return syscall5(
1450 .pread64,
1451 @as(u32, @bitCast(fd)),
1452 @intFromPtr(buf),
1453 count,
1454 offset_halves[0],
1455 offset_halves[1],
1456 );
1457 }
1458 } else {
1459 return syscall4(
1460 .pread64,
1461 @as(u32, @bitCast(fd)),
1462 @intFromPtr(buf),
1463 count,
1464 @as(u64, @bitCast(offset)),
1465 );
1466 }
1467}
1468
1469pub fn readv(fd: fd_t, iov: [*]const iovec, count: usize) usize {
1470 return syscall3(.readv, @as(u32, @bitCast(fd)), @intFromPtr(iov), count);
1471}
1472
1473pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: off_t) usize {
1474 const offset_u: u64 = @bitCast(offset);
1475 return syscall5(
1476 .preadv,
1477 @as(u32, @bitCast(fd)),
1478 @intFromPtr(iov),
1479 count,
1480 // Kernel expects the offset is split into largest natural word-size.
1481 // See following link for detail:
1482 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5
1483 @truncate(offset_u),
1484 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) @truncate(offset_u >> 32) else 0,
1485 );
1486}
1487
1488pub fn preadv2(fd: fd_t, iov: [*]const iovec, count: usize, offset: off_t, flags: kernel_rwf) usize {
1489 const offset_u: u64 = @bitCast(offset);
1490 return syscall6(
1491 .preadv2,
1492 @as(u32, @bitCast(fd)),
1493 @intFromPtr(iov),
1494 count,
1495 // See comments in preadv
1496 @truncate(offset_u),
1497 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) @truncate(offset_u >> 32) else 0,
1498 flags,
1499 );
1500}
1501
1502pub fn write(fd: fd_t, buf: [*]const u8, count: usize) usize {
1503 return syscall3(.write, @as(u32, @bitCast(fd)), @intFromPtr(buf), count);
1504}
1505
1506pub fn pwrite(fd: fd_t, buf: [*]const u8, count: usize, offset: off_t) usize {
1507 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
1508 const offset_halves = splitValue64(offset);
1509 if (require_aligned_register_pair) {
1510 return syscall6(
1511 .pwrite64,
1512 @as(u32, @bitCast(fd)),
1513 @intFromPtr(buf),
1514 count,
1515 0,
1516 offset_halves[0],
1517 offset_halves[1],
1518 );
1519 } else {
1520 return syscall5(
1521 .pwrite64,
1522 @as(u32, @bitCast(fd)),
1523 @intFromPtr(buf),
1524 count,
1525 offset_halves[0],
1526 offset_halves[1],
1527 );
1528 }
1529 } else {
1530 return syscall4(
1531 .pwrite64,
1532 @as(u32, @bitCast(fd)),
1533 @intFromPtr(buf),
1534 count,
1535 @as(u64, @bitCast(offset)),
1536 );
1537 }
1538}
1539
1540pub fn writev(fd: fd_t, iov: [*]const iovec_const, count: usize) usize {
1541 return syscall3(.writev, @as(u32, @bitCast(fd)), @intFromPtr(iov), count);
1542}
1543
1544pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: off_t) usize {
1545 const offset_u: u64 = @bitCast(offset);
1546 return syscall5(
1547 .pwritev,
1548 @as(u32, @bitCast(fd)),
1549 @intFromPtr(iov),
1550 count,
1551 // See comments in preadv
1552 @truncate(offset_u),
1553 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) @truncate(offset_u >> 32) else 0,
1554 );
1555}
1556
1557pub fn pwritev2(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: off_t, flags: kernel_rwf) usize {
1558 const offset_u: u64 = @bitCast(offset);
1559 return syscall6(
1560 .pwritev2,
1561 @as(u32, @bitCast(fd)),
1562 @intFromPtr(iov),
1563 count,
1564 // See comments in preadv
1565 @truncate(offset_u),
1566 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) @truncate(offset_u >> 32) else 0,
1567 flags,
1568 );
1569}
1570
1571pub fn rmdir(path: [*:0]const u8) usize {
1572 if (@hasField(SYS, "rmdir")) {
1573 return syscall1(.rmdir, @intFromPtr(path));
1574 } else {
1575 return syscall3(.unlinkat, @as(u32, @bitCast(@as(i32, AT.FDCWD))), @intFromPtr(path), AT.REMOVEDIR);
1576 }
1577}
1578
1579pub fn symlink(existing: [*:0]const u8, new: [*:0]const u8) usize {
1580 if (@hasField(SYS, "symlink")) {
1581 return syscall2(.symlink, @intFromPtr(existing), @intFromPtr(new));
1582 } else {
1583 return syscall3(.symlinkat, @intFromPtr(existing), @as(u32, @bitCast(@as(i32, AT.FDCWD))), @intFromPtr(new));
1584 }
1585}
1586
1587pub fn symlinkat(existing: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8) usize {
1588 return syscall3(.symlinkat, @intFromPtr(existing), @as(u32, @bitCast(newfd)), @intFromPtr(newpath));
1589}
1590
1591pub fn access(path: [*:0]const u8, mode: mode_t) usize {
1592 if (@hasField(SYS, "access")) {
1593 return syscall2(.access, @intFromPtr(path), mode);
1594 } else {
1595 return faccessat(AT.FDCWD, path, mode, 0);
1596 }
1597}
1598
1599pub fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: mode_t, flags: u32) usize {
1600 if (flags == 0) {
1601 return syscall3(.faccessat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), mode);
1602 }
1603 return syscall4(.faccessat2, @as(u32, @bitCast(dirfd)), @intFromPtr(path), mode, flags);
1604}
1605
1606pub fn acct(path: [*:0]const u8) usize {
1607 return syscall1(.acct, @intFromPtr(path));
1608}
1609
1610pub fn pipe(fd: *[2]fd_t) usize {
1611 if (native_arch.isMIPS() or native_arch.isSPARC()) {
1612 return syscall_pipe(fd);
1613 } else if (@hasField(SYS, "pipe")) {
1614 return syscall1(.pipe, @intFromPtr(fd));
1615 } else {
1616 return syscall2(.pipe2, @intFromPtr(fd), 0);
1617 }
1618}
1619
1620pub fn pipe2(fd: *[2]fd_t, flags: O) usize {
1621 return syscall2(.pipe2, @intFromPtr(fd), @as(u32, @bitCast(flags)));
1622}
1623
1624pub fn ftruncate(fd: fd_t, length: off_t) usize {
1625 if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
1626 const length_halves = splitValue64(length);
1627 if (require_aligned_register_pair) {
1628 return syscall4(
1629 .ftruncate64,
1630 @as(u32, @bitCast(fd)),
1631 0,
1632 length_halves[0],
1633 length_halves[1],
1634 );
1635 } else {
1636 return syscall3(
1637 .ftruncate64,
1638 @as(u32, @bitCast(fd)),
1639 length_halves[0],
1640 length_halves[1],
1641 );
1642 }
1643 } else {
1644 return syscall2(
1645 .ftruncate,
1646 @as(u32, @bitCast(fd)),
1647 @as(u64, @bitCast(length)),
1648 );
1649 }
1650}
1651
1652pub fn rename(old: [*:0]const u8, new: [*:0]const u8) usize {
1653 if (@hasField(SYS, "rename")) {
1654 return syscall2(.rename, @intFromPtr(old), @intFromPtr(new));
1655 } else if (@hasField(SYS, "renameat")) {
1656 return syscall4(
1657 .renameat,
1658 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1659 @intFromPtr(old),
1660 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1661 @intFromPtr(new),
1662 );
1663 } else {
1664 return syscall5(
1665 .renameat2,
1666 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1667 @intFromPtr(old),
1668 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1669 @intFromPtr(new),
1670 0,
1671 );
1672 }
1673}
1674
1675pub fn renameat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8) usize {
1676 if (@hasField(SYS, "renameat")) {
1677 return syscall4(
1678 .renameat,
1679 @as(u32, @bitCast(oldfd)),
1680 @intFromPtr(oldpath),
1681 @as(u32, @bitCast(newfd)),
1682 @intFromPtr(newpath),
1683 );
1684 } else {
1685 return syscall5(
1686 .renameat2,
1687 @as(u32, @bitCast(oldfd)),
1688 @intFromPtr(oldpath),
1689 @as(u32, @bitCast(newfd)),
1690 @intFromPtr(newpath),
1691 0,
1692 );
1693 }
1694}
1695
1696pub fn renameat2(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: RENAME) usize {
1697 return syscall5(
1698 .renameat2,
1699 @as(u32, @bitCast(oldfd)),
1700 @intFromPtr(oldpath),
1701 @as(u32, @bitCast(newfd)),
1702 @intFromPtr(newpath),
1703 @as(u32, @bitCast(flags)),
1704 );
1705}
1706
1707pub fn open(path: [*:0]const u8, flags: O, perm: mode_t) usize {
1708 if (@hasField(SYS, "open")) {
1709 return syscall3(.open, @intFromPtr(path), @as(u32, @bitCast(flags)), perm);
1710 } else {
1711 return syscall4(
1712 .openat,
1713 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1714 @intFromPtr(path),
1715 @as(u32, @bitCast(flags)),
1716 perm,
1717 );
1718 }
1719}
1720
1721pub fn create(path: [*:0]const u8, perm: mode_t) usize {
1722 return syscall2(.creat, @intFromPtr(path), perm);
1723}
1724
1725pub fn openat(dirfd: fd_t, path: [*:0]const u8, flags: O, mode: mode_t) usize {
1726 // dirfd could be negative, for example AT.FDCWD is -100
1727 return syscall4(.openat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), @as(u32, @bitCast(flags)), mode);
1728}
1729
1730/// See also `clone` (from the arch-specific include)
1731pub fn clone5(flags: usize, child_stack_ptr: usize, parent_tid: *pid_t, child_tid: *pid_t, newtls: usize) usize {
1732 return syscall5(.clone, flags, child_stack_ptr, @intFromPtr(parent_tid), @intFromPtr(child_tid), newtls);
1733}
1734
1735/// See also `clone` (from the arch-specific include)
1736pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
1737 return syscall2(.clone, flags, child_stack_ptr);
1738}
1739
1740/// This call cannot fail, and the return value is the caller's thread id
1741pub fn set_tid_address(tidptr: ?*pid_t) pid_t {
1742 return @intCast(@as(u32, @truncate(syscall1(.set_tid_address, @intFromPtr(tidptr)))));
1743}
1744
1745pub fn close(fd: fd_t) usize {
1746 return syscall1(.close, @as(u32, @bitCast(fd)));
1747}
1748
1749pub const CLOSE_RANGE = packed struct(u32) {
1750 _0: u1 = 0,
1751 /// Unshare the file descriptor table before closing file descriptors.
1752 UNSHARE: bool, // 0x00000001
1753 /// Set the FD_CLOEXEC bit instead of closing the file descriptor.
1754 CLOEXEC: bool, // 0x00000002
1755 _: u29 = 0,
1756};
1757
1758pub fn close_range(first: fd_t, last: fd_t, flags: CLOSE_RANGE) usize {
1759 return syscall3(.close_range, @as(u32, @bitCast(first)), @as(u32, @bitCast(last)), @as(u32, @bitCast(flags)));
1760}
1761
1762pub fn fchmod(fd: fd_t, mode: mode_t) usize {
1763 return syscall2(.fchmod, @as(u32, @bitCast(fd)), mode);
1764}
1765
1766pub fn chmod(path: [*:0]const u8, mode: mode_t) usize {
1767 if (@hasField(SYS, "chmod")) {
1768 return syscall2(.chmod, @intFromPtr(path), mode);
1769 } else {
1770 return fchmodat(AT.FDCWD, path, mode);
1771 }
1772}
1773
1774pub fn fchown(fd: fd_t, owner: uid_t, group: gid_t) usize {
1775 if (@hasField(SYS, "fchown32")) {
1776 return syscall3(.fchown32, @as(u32, @bitCast(fd)), owner, group);
1777 } else {
1778 return syscall3(.fchown, @as(u32, @bitCast(fd)), owner, group);
1779 }
1780}
1781
1782pub fn fchownat(fd: fd_t, path: [*:0]const u8, owner: uid_t, group: gid_t, flags: u32) usize {
1783 return syscall5(.fchownat, @as(u32, @bitCast(fd)), @intFromPtr(path), owner, group, flags);
1784}
1785
1786pub fn chown(path: [*:0]const u8, owner: uid_t, group: gid_t) usize {
1787 if (@hasField(SYS, "chown32")) {
1788 return syscall3(.chown32, @intFromPtr(path), owner, group);
1789 } else if (@hasField(SYS, "chown")) {
1790 return syscall3(.chown, @intFromPtr(path), owner, group);
1791 } else {
1792 return fchownat(AT.FDCWD, path, owner, group, 0);
1793 }
1794}
1795
1796pub fn lchown(path: [*:0]const u8, owner: uid_t, group: gid_t) usize {
1797 if (@hasField(SYS, "lchown32")) {
1798 return syscall3(.lchown32, @intFromPtr(path), owner, group);
1799 } else if (@hasField(SYS, "lchown")) {
1800 return syscall3(.lchown, @intFromPtr(path), owner, group);
1801 } else {
1802 return fchownat(AT.FDCWD, path, owner, group, AT.SYMLINK_NOFOLLOW);
1803 }
1804}
1805
1806pub fn fchmodat(fd: fd_t, path: [*:0]const u8, mode: mode_t) usize {
1807 return syscall3(.fchmodat, @as(u32, @bitCast(fd)), @intFromPtr(path), mode);
1808}
1809
1810pub fn fchmodat2(fd: fd_t, path: [*:0]const u8, mode: mode_t, flags: u32) usize {
1811 return syscall4(.fchmodat2, @as(u32, @bitCast(fd)), @intFromPtr(path), mode, flags);
1812}
1813
1814/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
1815pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) u32 {
1816 // NOTE: The offset parameter splitting is independent from the target
1817 // endianness.
1818 return syscall5(
1819 .llseek,
1820 @as(u32, @bitCast(fd)),
1821 @truncate(@as(u64, @bitCast(offset >> 32))),
1822 @truncate(@as(u64, @bitCast(offset))),
1823 @intFromPtr(result),
1824 whence,
1825 );
1826}
1827
1828/// Can only be called on 64 bit systems. For 32 bit see `llseek`.
1829pub fn lseek(fd: fd_t, offset: off_t, whence: u32) u64 {
1830 return switch (builtin.abi) {
1831 .gnuabin32,
1832 .muslabin32,
1833 .abin32,
1834 .gnux32,
1835 .muslx32,
1836 .x32,
1837 => syscall_lseek(fd, offset, whence),
1838 else => syscall3(.lseek, @as(u32, @bitCast(fd)), @as(u64, @bitCast(offset)), whence),
1839 };
1840}
1841
1842pub fn exit(status: i32) noreturn {
1843 _ = syscall1(.exit, @as(u32, @bitCast(status)));
1844 unreachable;
1845}
1846
1847pub fn exit_group(status: i32) noreturn {
1848 _ = syscall1(.exit_group, @as(u32, @bitCast(status)));
1849 unreachable;
1850}
1851
1852/// flags for the `reboot' system call.
1853pub const LINUX_REBOOT = struct {
1854 /// First magic value required to use _reboot() system call.
1855 pub const MAGIC1 = enum(u32) {
1856 MAGIC1 = 0xfee1dead,
1857 _,
1858 };
1859
1860 /// Second magic value required to use _reboot() system call.
1861 pub const MAGIC2 = enum(u32) {
1862 MAGIC2 = 672274793,
1863 MAGIC2A = 85072278,
1864 MAGIC2B = 369367448,
1865 MAGIC2C = 537993216,
1866 _,
1867 };
1868
1869 /// Commands accepted by the _reboot() system call.
1870 pub const CMD = enum(u32) {
1871 /// Restart system using default command and mode.
1872 RESTART = 0x01234567,
1873
1874 /// Stop OS and give system control to ROM monitor, if any.
1875 HALT = 0xCDEF0123,
1876
1877 /// Ctrl-Alt-Del sequence causes RESTART command.
1878 CAD_ON = 0x89ABCDEF,
1879
1880 /// Ctrl-Alt-Del sequence sends SIGINT to init task.
1881 CAD_OFF = 0x00000000,
1882
1883 /// Stop OS and remove all power from system, if possible.
1884 POWER_OFF = 0x4321FEDC,
1885
1886 /// Restart system using given command string.
1887 RESTART2 = 0xA1B2C3D4,
1888
1889 /// Suspend system using software suspend if compiled in.
1890 SW_SUSPEND = 0xD000FCE2,
1891
1892 /// Restart system using a previously loaded Linux kernel
1893 KEXEC = 0x45584543,
1894
1895 _,
1896 };
1897};
1898
1899pub fn reboot(magic: LINUX_REBOOT.MAGIC1, magic2: LINUX_REBOOT.MAGIC2, cmd: LINUX_REBOOT.CMD, arg: ?*const anyopaque) usize {
1900 return std.os.linux.syscall4(
1901 .reboot,
1902 @backingInt(magic),
1903 @backingInt(magic2),
1904 @backingInt(cmd),
1905 @intFromPtr(arg),
1906 );
1907}
1908
1909pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
1910 return syscall3(.getrandom, @intFromPtr(buf), count, flags);
1911}
1912
1913pub fn kill(pid: pid_t, sig: SIG) usize {
1914 return syscall2(.kill, @as(u32, @bitCast(pid)), @backingInt(sig));
1915}
1916
1917pub fn tkill(tid: pid_t, sig: SIG) usize {
1918 return syscall2(.tkill, @as(u32, @bitCast(tid)), @backingInt(sig));
1919}
1920
1921pub fn tgkill(tgid: pid_t, tid: pid_t, sig: SIG) usize {
1922 return syscall3(.tgkill, @as(u32, @bitCast(tgid)), @as(u32, @bitCast(tid)), @backingInt(sig));
1923}
1924
1925pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) usize {
1926 if (@hasField(SYS, "link")) {
1927 return syscall2(
1928 .link,
1929 @intFromPtr(oldpath),
1930 @intFromPtr(newpath),
1931 );
1932 } else {
1933 return syscall5(
1934 .linkat,
1935 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1936 @intFromPtr(oldpath),
1937 @as(u32, @bitCast(@as(i32, AT.FDCWD))),
1938 @intFromPtr(newpath),
1939 0,
1940 );
1941 }
1942}
1943
1944pub fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: u32) usize {
1945 return syscall5(
1946 .linkat,
1947 @as(u32, @bitCast(oldfd)),
1948 @intFromPtr(oldpath),
1949 @as(u32, @bitCast(newfd)),
1950 @intFromPtr(newpath),
1951 flags,
1952 );
1953}
1954
1955pub fn unlink(path: [*:0]const u8) usize {
1956 if (@hasField(SYS, "unlink")) {
1957 return syscall1(.unlink, @intFromPtr(path));
1958 } else {
1959 return syscall3(.unlinkat, @as(u32, @bitCast(@as(i32, AT.FDCWD))), @intFromPtr(path), 0);
1960 }
1961}
1962
1963pub fn unlinkat(dirfd: fd_t, path: [*:0]const u8, flags: u32) usize {
1964 return syscall3(.unlinkat, @as(u32, @bitCast(dirfd)), @intFromPtr(path), flags);
1965}
1966
1967pub fn waitpid(pid: pid_t, status: *i32, flags: u32) usize {
1968 return syscall4(.wait4, @as(u32, @bitCast(pid)), @intFromPtr(status), flags, 0);
1969}
1970
1971pub fn wait4(pid: pid_t, status: *i32, flags: u32, usage: ?*rusage) usize {
1972 return syscall4(
1973 .wait4,
1974 @as(u32, @bitCast(pid)),
1975 @intFromPtr(status),
1976 flags,
1977 @intFromPtr(usage),
1978 );
1979}
1980
1981pub fn waitid(id_type: P, id: pid_t, infop: *siginfo_t, flags: u32, usage: ?*rusage) usize {
1982 return syscall5(
1983 .waitid,
1984 @backingInt(id_type),
1985 @as(u32, @bitCast(id)),
1986 @intFromPtr(infop),
1987 flags,
1988 @intFromPtr(usage),
1989 );
1990}
1991
1992pub const F = struct {
1993 pub const DUPFD = 0;
1994 pub const GETFD = 1;
1995 pub const SETFD = 2;
1996 pub const GETFL = 3;
1997 pub const SETFL = 4;
1998
1999 pub const GETLK = GET_SET_LK.GETLK;
2000 pub const SETLK = GET_SET_LK.SETLK;
2001 pub const SETLKW = GET_SET_LK.SETLKW;
2002
2003 pub const SETOWN = GET_SET_OWN.SETOWN;
2004 pub const GETOWN = GET_SET_OWN.GETOWN;
2005
2006 const GET_SET_LK = switch (native_arch) {
2007 .mips, .mipsel => struct {
2008 const GETLK = 33;
2009 const SETLK = 34;
2010 const SETLKW = 35;
2011 },
2012 .mips64, .mips64el => switch (native_abi) {
2013 .gnuabin32, .muslabin32, .abin32 => struct {
2014 const GETLK = 33;
2015 const SETLK = 34;
2016 const SETLKW = 35;
2017 },
2018 else => struct {
2019 const GETLK = 14;
2020 const SETLK = 6;
2021 const SETLKW = 7;
2022 },
2023 },
2024 .alpha, .sparc, .sparc64 => struct {
2025 const GETLK = 7;
2026 const SETLK = 8;
2027 const SETLKW = 9;
2028 },
2029 .hppa, .hppa64 => struct {
2030 const GETLK = 8;
2031 const SETLK = 9;
2032 const SETLKW = 10;
2033 },
2034 else => if (@sizeOf(usize) == 8) struct {
2035 const GETLK = 5;
2036 const SETLK = 6;
2037 const SETLKW = 7;
2038 } else struct {
2039 const GETLK = 12;
2040 const SETLK = 13;
2041 const SETLKW = 14;
2042 },
2043 };
2044 const GET_SET_OWN = switch (native_arch) {
2045 .mips, .mipsel, .mips64, .mips64el => struct {
2046 const GETOWN = 23;
2047 const SETOWN = 24;
2048 },
2049 .alpha, .sparc, .sparc64 => struct {
2050 const GETOWN = 5;
2051 const SETOWN = 6;
2052 },
2053 .hppa, .hppa64 => struct {
2054 const GETOWN = 11;
2055 const SETOWN = 12;
2056 },
2057 else => struct {
2058 const GETOWN = 8;
2059 const SETOWN = 9;
2060 },
2061 };
2062
2063 pub const SETSIG = if (is_hppa) 13 else 10;
2064 pub const GETSIG = if (is_hppa) 14 else 11;
2065
2066 pub const SETOWN_EX = 15;
2067 pub const GETOWN_EX = 16;
2068
2069 pub const GETOWNER_UIDS = 17;
2070
2071 pub const OFD_GETLK = 36;
2072 pub const OFD_SETLK = 37;
2073 pub const OFD_SETLKW = 38;
2074
2075 pub const RDLCK = if (is_sparc) 1 else 0;
2076 pub const WRLCK = if (is_sparc) 2 else 1;
2077 pub const UNLCK = if (is_sparc) 3 else if (native_arch == .alpha) 8 else 2;
2078
2079 pub const LINUX_SPECIFIC_BASE = 1024;
2080
2081 pub const SETLEASE = LINUX_SPECIFIC_BASE + 0;
2082 pub const GETLEASE = LINUX_SPECIFIC_BASE + 1;
2083 pub const NOTIFY = LINUX_SPECIFIC_BASE + 2;
2084 pub const DUPFD_QUERY = LINUX_SPECIFIC_BASE + 3;
2085 pub const CREATED_QUERY = LINUX_SPECIFIC_BASE + 4;
2086 pub const CANCELLK = LINUX_SPECIFIC_BASE + 5;
2087 pub const DUPFD_CLOEXEC = LINUX_SPECIFIC_BASE + 6;
2088 pub const SETPIPE_SZ = LINUX_SPECIFIC_BASE + 7;
2089 pub const GETPIPE_SZ = LINUX_SPECIFIC_BASE + 8;
2090 pub const ADD_SEALS = LINUX_SPECIFIC_BASE + 9;
2091 pub const GET_SEALS = LINUX_SPECIFIC_BASE + 10;
2092
2093 pub const SEAL_SEAL = 0x0001;
2094 pub const SEAL_SHRINK = 0x0002;
2095 pub const SEAL_GROW = 0x0004;
2096 pub const SEAL_WRITE = 0x0008;
2097 pub const SEAL_FUTURE_WRITE = 0x0010;
2098 pub const SEAL_EXEC = 0x0020;
2099
2100 pub const GET_RW_HINT = LINUX_SPECIFIC_BASE + 11;
2101 pub const SET_RW_HINT = LINUX_SPECIFIC_BASE + 12;
2102 pub const GET_FILE_RW_HINT = LINUX_SPECIFIC_BASE + 13;
2103 pub const SET_FILE_RW_HINT = LINUX_SPECIFIC_BASE + 14;
2104};
2105
2106pub const F_OWNER = enum(i32) {
2107 TID = 0,
2108 PID = 1,
2109 PGRP = 2,
2110 _,
2111};
2112
2113pub const f_owner_ex = extern struct {
2114 type: F_OWNER,
2115 pid: pid_t,
2116};
2117
2118pub const Flock = extern struct {
2119 type: i16,
2120 whence: i16,
2121 start: off_t,
2122 len: off_t,
2123 pid: pid_t,
2124 _unused: if (is_sparc) i16 else void,
2125};
2126
2127pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) usize {
2128 if (@hasField(SYS, "fcntl64")) {
2129 return syscall3(.fcntl64, @as(u32, @bitCast(fd)), @as(u32, @bitCast(cmd)), arg);
2130 } else {
2131 return syscall3(.fcntl, @as(u32, @bitCast(fd)), @as(u32, @bitCast(cmd)), arg);
2132 }
2133}
2134
2135pub fn flock(fd: fd_t, operation: i32) usize {
2136 return syscall2(.flock, @as(u32, @bitCast(fd)), @as(u32, @bitCast(operation)));
2137}
2138
2139pub const Elf_Symndx = switch (native_arch) {
2140 .alpha, .s390x => u64,
2141 else => u32,
2142};
2143
2144// We must follow the C calling convention when we call into the VDSO
2145const VdsoClockGettime = *align(1) const fn (clockid_t, *timespec) callconv(.c) usize;
2146var vdso_clock_gettime: ?VdsoClockGettime = &init_vdso_clock_gettime;
2147
2148pub fn clock_gettime(clk_id: clockid_t, tp: *timespec) usize {
2149 if (VDSO != void) {
2150 const ptr = @atomicLoad(?VdsoClockGettime, &vdso_clock_gettime, .unordered);
2151 if (ptr) |f| {
2152 const rc = f(clk_id, tp);
2153 switch (rc) {
2154 0, @as(usize, @bitCast(-@as(isize, @backingInt(E.INVAL)))) => return rc,
2155 else => {},
2156 }
2157 }
2158 }
2159 return syscall2(
2160 if (@hasField(SYS, "clock_gettime") and native_arch != .hexagon) .clock_gettime else .clock_gettime64,
2161 @backingInt(clk_id),
2162 @intFromPtr(tp),
2163 );
2164}
2165
2166fn init_vdso_clock_gettime(clk: clockid_t, ts: *timespec) callconv(.c) usize {
2167 const ptr: ?VdsoClockGettime = @ptrFromInt(vdso.lookup(VDSO.CGT_VER, VDSO.CGT_SYM));
2168 // Note that we may not have a VDSO at all, update the stub address anyway
2169 // so that clock_gettime will fall back on the good old (and slow) syscall
2170 @atomicStore(?VdsoClockGettime, &vdso_clock_gettime, ptr, .monotonic);
2171 // Call into the VDSO if available
2172 if (ptr) |f| return f(clk, ts);
2173 return @bitCast(-@as(isize, @backingInt(E.NOSYS)));
2174}
2175
2176pub fn clock_getres(clk_id: clockid_t, tp: *timespec) usize {
2177 return syscall2(
2178 if (@hasField(SYS, "clock_getres") and native_arch != .hexagon) .clock_getres else .clock_getres_time64,
2179 @backingInt(clk_id),
2180 @intFromPtr(tp),
2181 );
2182}
2183
2184pub fn clock_settime(clk_id: clockid_t, tp: *const timespec) usize {
2185 return syscall2(
2186 if (@hasField(SYS, "clock_settime") and native_arch != .hexagon) .clock_settime else .clock_settime64,
2187 @backingInt(clk_id),
2188 @intFromPtr(tp),
2189 );
2190}
2191
2192pub fn clock_nanosleep(clockid: clockid_t, flags: TIMER, request: *const timespec, remain: ?*timespec) usize {
2193 return syscall4(
2194 if (@hasField(SYS, "clock_nanosleep") and native_arch != .hexagon) .clock_nanosleep else .clock_nanosleep_time64,
2195 @backingInt(clockid),
2196 @as(u32, @bitCast(flags)),
2197 @intFromPtr(request),
2198 @intFromPtr(remain),
2199 );
2200}
2201
2202pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) usize {
2203 return syscall2(.gettimeofday, @intFromPtr(tv), @intFromPtr(tz));
2204}
2205
2206pub fn settimeofday(tv: *const timeval, tz: *const timezone) usize {
2207 return syscall2(.settimeofday, @intFromPtr(tv), @intFromPtr(tz));
2208}
2209
2210pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
2211 return syscall2(.nanosleep, @intFromPtr(req), @intFromPtr(rem));
2212}
2213
2214pub fn pause() usize {
2215 if (@hasField(SYS, "pause")) {
2216 return syscall0(.pause);
2217 } else {
2218 return syscall4(.ppoll, 0, 0, 0, 0);
2219 }
2220}
2221
2222pub fn setuid(uid: uid_t) usize {
2223 if (@hasField(SYS, "setuid32")) {
2224 return syscall1(.setuid32, uid);
2225 } else {
2226 return syscall1(.setuid, uid);
2227 }
2228}
2229
2230pub fn setgid(gid: gid_t) usize {
2231 if (@hasField(SYS, "setgid32")) {
2232 return syscall1(.setgid32, gid);
2233 } else {
2234 return syscall1(.setgid, gid);
2235 }
2236}
2237
2238pub fn setreuid(ruid: uid_t, euid: uid_t) usize {
2239 if (@hasField(SYS, "setreuid32")) {
2240 return syscall2(.setreuid32, ruid, euid);
2241 } else {
2242 return syscall2(.setreuid, ruid, euid);
2243 }
2244}
2245
2246pub fn setregid(rgid: gid_t, egid: gid_t) usize {
2247 if (@hasField(SYS, "setregid32")) {
2248 return syscall2(.setregid32, rgid, egid);
2249 } else {
2250 return syscall2(.setregid, rgid, egid);
2251 }
2252}
2253
2254pub fn getuid() uid_t {
2255 if (@hasField(SYS, "getuid32")) {
2256 return @as(uid_t, @intCast(syscall0(.getuid32)));
2257 } else {
2258 return @as(uid_t, @intCast(syscall0(.getuid)));
2259 }
2260}
2261
2262pub fn getgid() gid_t {
2263 if (@hasField(SYS, "getgid32")) {
2264 return @as(gid_t, @intCast(syscall0(.getgid32)));
2265 } else {
2266 return @as(gid_t, @intCast(syscall0(.getgid)));
2267 }
2268}
2269
2270pub fn geteuid() uid_t {
2271 if (@hasField(SYS, "geteuid32")) {
2272 return @as(uid_t, @intCast(syscall0(.geteuid32)));
2273 } else {
2274 return @as(uid_t, @intCast(syscall0(.geteuid)));
2275 }
2276}
2277
2278pub fn getegid() gid_t {
2279 if (@hasField(SYS, "getegid32")) {
2280 return @as(gid_t, @intCast(syscall0(.getegid32)));
2281 } else {
2282 return @as(gid_t, @intCast(syscall0(.getegid)));
2283 }
2284}
2285
2286pub fn seteuid(euid: uid_t) usize {
2287 // We use setresuid here instead of setreuid to ensure that the saved uid
2288 // is not changed. This is what musl and recent glibc versions do as well.
2289 //
2290 // The setresuid(2) man page says that if -1 is passed the corresponding
2291 // id will not be changed. Since uid_t is unsigned, this wraps around to the
2292 // max value in C.
2293 comptime assert(@typeInfo(uid_t) == .int and @typeInfo(uid_t).int.signedness == .unsigned);
2294 return setresuid(maxInt(uid_t), euid, maxInt(uid_t));
2295}
2296
2297pub fn setegid(egid: gid_t) usize {
2298 // We use setresgid here instead of setregid to ensure that the saved uid
2299 // is not changed. This is what musl and recent glibc versions do as well.
2300 //
2301 // The setresgid(2) man page says that if -1 is passed the corresponding
2302 // id will not be changed. Since gid_t is unsigned, this wraps around to the
2303 // max value in C.
2304 comptime assert(@typeInfo(uid_t) == .int and @typeInfo(uid_t).int.signedness == .unsigned);
2305 return setresgid(maxInt(gid_t), egid, maxInt(gid_t));
2306}
2307
2308pub fn getresuid(ruid: *uid_t, euid: *uid_t, suid: *uid_t) usize {
2309 if (@hasField(SYS, "getresuid32")) {
2310 return syscall3(.getresuid32, @intFromPtr(ruid), @intFromPtr(euid), @intFromPtr(suid));
2311 } else {
2312 return syscall3(.getresuid, @intFromPtr(ruid), @intFromPtr(euid), @intFromPtr(suid));
2313 }
2314}
2315
2316pub fn getresgid(rgid: *gid_t, egid: *gid_t, sgid: *gid_t) usize {
2317 if (@hasField(SYS, "getresgid32")) {
2318 return syscall3(.getresgid32, @intFromPtr(rgid), @intFromPtr(egid), @intFromPtr(sgid));
2319 } else {
2320 return syscall3(.getresgid, @intFromPtr(rgid), @intFromPtr(egid), @intFromPtr(sgid));
2321 }
2322}
2323
2324pub fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) usize {
2325 if (@hasField(SYS, "setresuid32")) {
2326 return syscall3(.setresuid32, ruid, euid, suid);
2327 } else {
2328 return syscall3(.setresuid, ruid, euid, suid);
2329 }
2330}
2331
2332pub fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) usize {
2333 if (@hasField(SYS, "setresgid32")) {
2334 return syscall3(.setresgid32, rgid, egid, sgid);
2335 } else {
2336 return syscall3(.setresgid, rgid, egid, sgid);
2337 }
2338}
2339
2340pub fn setpgid(pid: pid_t, pgid: pid_t) usize {
2341 return syscall2(.setpgid, @as(u32, @bitCast(pid)), @as(u32, @bitCast(pgid)));
2342}
2343
2344pub fn getpgid(pid: pid_t) usize {
2345 return syscall1(.getpgid, @as(u32, @bitCast(pid)));
2346}
2347
2348pub fn getgroups(size: usize, list: ?[*]gid_t) usize {
2349 if (@hasField(SYS, "getgroups32")) {
2350 return syscall2(.getgroups32, size, @intFromPtr(list));
2351 } else {
2352 return syscall2(.getgroups, size, @intFromPtr(list));
2353 }
2354}
2355
2356pub fn setgroups(size: usize, list: [*]const gid_t) usize {
2357 if (@hasField(SYS, "setgroups32")) {
2358 return syscall2(.setgroups32, size, @intFromPtr(list));
2359 } else {
2360 return syscall2(.setgroups, size, @intFromPtr(list));
2361 }
2362}
2363
2364pub fn setsid() usize {
2365 return syscall0(.setsid);
2366}
2367
2368pub fn getsid(pid: pid_t) usize {
2369 return syscall1(.getsid, @as(u32, @bitCast(pid)));
2370}
2371
2372pub fn getpid() pid_t {
2373 // Casts result to a pid_t, safety-checking >= 0, because getpid() cannot fail
2374 return @intCast(@as(u32, @truncate(syscall0(.getpid))));
2375}
2376
2377pub fn getppid() pid_t {
2378 // Casts result to a pid_t, safety-checking >= 0, because getppid() cannot fail
2379 return @intCast(@as(u32, @truncate(syscall0(.getppid))));
2380}
2381
2382pub fn gettid() pid_t {
2383 // Casts result to a pid_t, safety-checking >= 0, because gettid() cannot fail
2384 return @intCast(@as(u32, @truncate(syscall0(.gettid))));
2385}
2386
2387pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*sigset_t) usize {
2388 return syscall4(.rt_sigprocmask, flags, @intFromPtr(set), @intFromPtr(oldset), NSIG / 8);
2389}
2390
2391pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
2392 assert(@backingInt(sig) > 0);
2393 assert(@backingInt(sig) < NSIG);
2394 assert(sig != .KILL);
2395 assert(sig != .STOP);
2396
2397 var ksa: k_sigaction = undefined;
2398 var oldksa: k_sigaction = undefined;
2399 const mask_size = @sizeOf(@TypeOf(ksa.mask));
2400
2401 if (act) |new| {
2402 if (native_arch == .hexagon or is_loongarch or is_mips or native_arch == .or1k or is_riscv) {
2403 ksa = .{
2404 .handler = new.handler.handler,
2405 .flags = new.flags,
2406 .mask = new.mask,
2407 };
2408 } else {
2409 // Zig needs to install our arch restorer function with any signal handler, so
2410 // must copy the Sigaction struct
2411 const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) &restore_rt else &restore;
2412 ksa = .{
2413 .handler = new.handler.handler,
2414 .flags = new.flags | SA.RESTORER,
2415 .mask = new.mask,
2416 .restorer = @ptrCast(restorer_fn),
2417 };
2418 }
2419 }
2420
2421 const ksa_arg = if (act != null) @intFromPtr(&ksa) else 0;
2422 const oldksa_arg = if (oact != null) @intFromPtr(&oldksa) else 0;
2423
2424 const result = switch (native_arch) {
2425 // The sparc version of rt_sigaction needs the restorer function to be passed as an argument too.
2426 .sparc, .sparc64 => syscall5(.rt_sigaction, @backingInt(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
2427 else => syscall4(.rt_sigaction, @backingInt(sig), ksa_arg, oldksa_arg, mask_size),
2428 };
2429 if (errno(result) != .SUCCESS) return result;
2430
2431 if (oact) |old| {
2432 old.handler.handler = oldksa.handler;
2433 old.flags = oldksa.flags;
2434 old.mask = oldksa.mask;
2435 }
2436
2437 return 0;
2438}
2439
2440/// Defined as one greater than the largest defined signal number.
2441pub const NSIG = if (is_mips) 128 else 65;
2442
2443/// Linux kernel's sigset_t. This is logically 64-bit on most
2444/// architectures, but 128-bit on MIPS. Contrast with the 1024-bit
2445/// sigset_t exported by the glibc and musl library ABIs.
2446pub const sigset_t = [(NSIG - 1 + 7) / @bitSizeOf(SigsetElement)]SigsetElement;
2447
2448const SigsetElement = c_ulong;
2449
2450const sigset_len = @typeInfo(sigset_t).array.len;
2451
2452/// Zig's SIGRTMIN, but is a function for compatibility with glibc
2453pub fn sigrtmin() u8 {
2454 // Default is 32 in the kernel UAPI: https://github.com/torvalds/linux/blob/78109c591b806e41987e0b83390e61d675d1f724/include/uapi/asm-generic/signal.h#L50
2455 // AFAICT, all architectures that override this also set it to 32:
2456 // https://github.com/search?q=repo%3Atorvalds%2Flinux+sigrtmin+path%3Auapi&type=code
2457 return 32;
2458}
2459
2460/// Zig's SIGRTMAX, but is a function for compatibility with glibc
2461pub fn sigrtmax() u8 {
2462 return NSIG - 1;
2463}
2464
2465/// Zig's version of sigemptyset. Returns initialized sigset_t.
2466pub fn sigemptyset() sigset_t {
2467 return @splat(0);
2468}
2469
2470/// Zig's version of sigfillset. Returns initalized sigset_t.
2471pub fn sigfillset() sigset_t {
2472 return @splat(~@as(SigsetElement, 0));
2473}
2474
2475fn sigset_bit_index(sig: SIG) struct { word: usize, mask: SigsetElement } {
2476 assert(@backingInt(sig) > 0);
2477 assert(@backingInt(sig) < NSIG);
2478 const bit = @backingInt(sig) - 1;
2479 return .{
2480 .word = bit / @bitSizeOf(SigsetElement),
2481 .mask = @as(SigsetElement, 1) << @truncate(bit % @bitSizeOf(SigsetElement)),
2482 };
2483}
2484
2485pub fn sigaddset(set: *sigset_t, sig: SIG) void {
2486 const index = sigset_bit_index(sig);
2487 (set.*)[index.word] |= index.mask;
2488}
2489
2490pub fn sigdelset(set: *sigset_t, sig: SIG) void {
2491 const index = sigset_bit_index(sig);
2492 (set.*)[index.word] ^= index.mask;
2493}
2494
2495pub fn sigismember(set: *const sigset_t, sig: SIG) bool {
2496 const index = sigset_bit_index(sig);
2497 return ((set.*)[index.word] & index.mask) != 0;
2498}
2499
2500pub fn getsockname(fd: fd_t, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
2501 if (native_arch == .x86) {
2502 return socketcall(SC.getsockname, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len) });
2503 }
2504 return syscall3(.getsockname, @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len));
2505}
2506
2507pub fn getpeername(fd: fd_t, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
2508 if (native_arch == .x86) {
2509 return socketcall(SC.getpeername, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len) });
2510 }
2511 return syscall3(.getpeername, @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len));
2512}
2513
2514pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
2515 if (native_arch == .x86) {
2516 return socketcall(SC.socket, &[3]usize{ domain, socket_type, protocol });
2517 }
2518 return syscall3(.socket, domain, socket_type, protocol);
2519}
2520
2521pub fn setsockopt(fd: fd_t, level: i32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
2522 if (native_arch == .x86) {
2523 return socketcall(SC.setsockopt, &[5]usize{ @as(u32, @bitCast(fd)), @as(usize, @bitCast(@as(isize, level))), optname, @intFromPtr(optval), @as(usize, @intCast(optlen)) });
2524 }
2525 return syscall5(.setsockopt, @as(u32, @bitCast(fd)), @as(usize, @bitCast(@as(isize, level))), optname, @intFromPtr(optval), @as(usize, @intCast(optlen)));
2526}
2527
2528pub fn getsockopt(fd: fd_t, level: i32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
2529 if (native_arch == .x86) {
2530 return socketcall(SC.getsockopt, &[5]usize{ @as(u32, @bitCast(fd)), @as(usize, @bitCast(@as(isize, level))), optname, @intFromPtr(optval), @intFromPtr(optlen) });
2531 }
2532 return syscall5(.getsockopt, @as(u32, @bitCast(fd)), @as(usize, @bitCast(@as(isize, level))), optname, @intFromPtr(optval), @intFromPtr(optlen));
2533}
2534
2535pub fn sendmsg(fd: fd_t, msg: *const msghdr_const, flags: u32) usize {
2536 if (native_arch == .x86) {
2537 return socketcall(SC.sendmsg, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(msg), flags });
2538 } else {
2539 return syscall3(.sendmsg, @as(u32, @bitCast(fd)), @intFromPtr(msg), flags);
2540 }
2541}
2542
2543pub fn sendmmsg(fd: fd_t, msgvec: [*]mmsghdr, vlen: u32, flags: u32) usize {
2544 return syscall4(.sendmmsg, @as(u32, @bitCast(fd)), @intFromPtr(msgvec), vlen, flags);
2545}
2546
2547pub fn connect(fd: fd_t, addr: *const anyopaque, len: socklen_t) usize {
2548 if (native_arch == .x86) {
2549 return socketcall(SC.connect, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), len });
2550 } else {
2551 return syscall3(.connect, @as(u32, @bitCast(fd)), @intFromPtr(addr), len);
2552 }
2553}
2554
2555pub fn recvmsg(fd: fd_t, msg: *msghdr, flags: u32) usize {
2556 if (native_arch == .x86) {
2557 return socketcall(SC.recvmsg, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(msg), flags });
2558 } else {
2559 return syscall3(.recvmsg, @as(u32, @bitCast(fd)), @intFromPtr(msg), flags);
2560 }
2561}
2562
2563pub fn recvmmsg(fd: fd_t, msgvec: ?[*]mmsghdr, vlen: u32, flags: u32, timeout: ?*timespec) usize {
2564 return syscall5(
2565 if (@hasField(SYS, "recvmmsg") and native_arch != .hexagon) .recvmmsg else .recvmmsg_time64,
2566 @as(u32, @bitCast(fd)),
2567 @intFromPtr(msgvec),
2568 vlen,
2569 flags,
2570 @intFromPtr(timeout),
2571 );
2572}
2573
2574pub fn recvfrom(
2575 fd: fd_t,
2576 noalias buf: [*]u8,
2577 len: usize,
2578 flags: u32,
2579 noalias addr: ?*sockaddr,
2580 noalias alen: ?*socklen_t,
2581) usize {
2582 if (native_arch == .x86) {
2583 return socketcall(SC.recvfrom, &[6]usize{ @as(u32, @bitCast(fd)), @intFromPtr(buf), len, flags, @intFromPtr(addr), @intFromPtr(alen) });
2584 } else {
2585 return syscall6(.recvfrom, @as(u32, @bitCast(fd)), @intFromPtr(buf), len, flags, @intFromPtr(addr), @intFromPtr(alen));
2586 }
2587}
2588
2589pub fn shutdown(fd: fd_t, how: i32) usize {
2590 if (native_arch == .x86) {
2591 return socketcall(SC.shutdown, &[2]usize{ @as(u32, @bitCast(fd)), @as(u32, @bitCast(how)) });
2592 }
2593 return syscall2(.shutdown, @as(u32, @bitCast(fd)), @as(u32, @bitCast(how)));
2594}
2595
2596pub fn bind(fd: fd_t, addr: *const sockaddr, len: socklen_t) usize {
2597 if (native_arch == .x86) {
2598 return socketcall(SC.bind, &[3]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), len });
2599 }
2600 return syscall3(.bind, @as(u32, @bitCast(fd)), @intFromPtr(addr), len);
2601}
2602
2603pub fn listen(fd: fd_t, backlog: u32) usize {
2604 if (native_arch == .x86) {
2605 return socketcall(SC.listen, &[2]usize{ @as(u32, @bitCast(fd)), backlog });
2606 }
2607 return syscall2(.listen, @as(u32, @bitCast(fd)), backlog);
2608}
2609
2610pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
2611 if (native_arch == .x86) {
2612 return socketcall(SC.sendto, &[6]usize{ @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(buf), len, flags, @intFromPtr(addr), @as(usize, @intCast(alen)) });
2613 }
2614 return syscall6(.sendto, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(buf), len, flags, @intFromPtr(addr), @as(usize, @intCast(alen)));
2615}
2616
2617pub fn sendfile(outfd: fd_t, infd: fd_t, offset: ?*off_t, count: usize) usize {
2618 return syscall4(
2619 if (@hasField(SYS, "sendfile64")) .sendfile64 else .sendfile,
2620 @as(u32, @bitCast(outfd)),
2621 @as(u32, @bitCast(infd)),
2622 @intFromPtr(offset),
2623 count,
2624 );
2625}
2626
2627pub fn socketpair(domain: u32, socket_type: u32, protocol: u32, fd: *[2]fd_t) usize {
2628 if (native_arch == .x86) {
2629 return socketcall(SC.socketpair, &[4]usize{ domain, socket_type, protocol, @intFromPtr(fd) });
2630 }
2631 return syscall4(.socketpair, domain, socket_type, protocol, @intFromPtr(fd));
2632}
2633
2634pub fn accept(fd: fd_t, noalias addr: ?*sockaddr, noalias len: ?*socklen_t) usize {
2635 if (native_arch == .x86) {
2636 return socketcall(SC.accept, &[4]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len), 0 });
2637 }
2638 return accept4(fd, addr, len, 0);
2639}
2640
2641pub fn accept4(fd: fd_t, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flags: u32) usize {
2642 if (native_arch == .x86) {
2643 return socketcall(SC.accept4, &[4]usize{ @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len), flags });
2644 }
2645 return syscall4(.accept4, @as(u32, @bitCast(fd)), @intFromPtr(addr), @intFromPtr(len), flags);
2646}
2647
2648pub fn statx(dirfd: fd_t, path: [*:0]const u8, flags: u32, mask: STATX, statx_buf: *Statx) usize {
2649 return syscall5(
2650 .statx,
2651 @as(u32, @bitCast(dirfd)),
2652 @intFromPtr(path),
2653 flags,
2654 @as(u32, @bitCast(mask)),
2655 @intFromPtr(statx_buf),
2656 );
2657}
2658
2659pub fn listxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize {
2660 return syscall3(.listxattr, @intFromPtr(path), @intFromPtr(list), size);
2661}
2662
2663pub fn llistxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize {
2664 return syscall3(.llistxattr, @intFromPtr(path), @intFromPtr(list), size);
2665}
2666
2667pub fn flistxattr(fd: fd_t, list: [*]u8, size: usize) usize {
2668 return syscall3(.flistxattr, @as(u32, @bitCast(fd)), @intFromPtr(list), size);
2669}
2670
2671pub fn getxattr(path: [*:0]const u8, name: [*:0]const u8, value: [*]u8, size: usize) usize {
2672 return syscall4(.getxattr, @intFromPtr(path), @intFromPtr(name), @intFromPtr(value), size);
2673}
2674
2675pub fn lgetxattr(path: [*:0]const u8, name: [*:0]const u8, value: [*]u8, size: usize) usize {
2676 return syscall4(.lgetxattr, @intFromPtr(path), @intFromPtr(name), @intFromPtr(value), size);
2677}
2678
2679pub fn fgetxattr(fd: fd_t, name: [*:0]const u8, value: [*]u8, size: usize) usize {
2680 return syscall4(.fgetxattr, @as(u32, @bitCast(fd)), @intFromPtr(name), @intFromPtr(value), size);
2681}
2682
2683pub fn setxattr(path: [*:0]const u8, name: [*:0]const u8, value: [*]const u8, size: usize, flags: usize) usize {
2684 return syscall5(.setxattr, @intFromPtr(path), @intFromPtr(name), @intFromPtr(value), size, flags);
2685}
2686
2687pub fn lsetxattr(path: [*:0]const u8, name: [*:0]const u8, value: [*]const u8, size: usize, flags: usize) usize {
2688 return syscall5(.lsetxattr, @intFromPtr(path), @intFromPtr(name), @intFromPtr(value), size, flags);
2689}
2690
2691pub fn fsetxattr(fd: fd_t, name: [*:0]const u8, value: [*]const u8, size: usize, flags: usize) usize {
2692 return syscall5(.fsetxattr, @as(u32, @bitCast(fd)), @intFromPtr(name), @intFromPtr(value), size, flags);
2693}
2694
2695pub fn removexattr(path: [*:0]const u8, name: [*:0]const u8) usize {
2696 return syscall2(.removexattr, @intFromPtr(path), @intFromPtr(name));
2697}
2698
2699pub fn lremovexattr(path: [*:0]const u8, name: [*:0]const u8) usize {
2700 return syscall2(.lremovexattr, @intFromPtr(path), @intFromPtr(name));
2701}
2702
2703pub fn fremovexattr(fd: fd_t, name: [*:0]const u8) usize {
2704 return syscall2(.fremovexattr, @as(u32, @bitCast(fd)), @intFromPtr(name));
2705}
2706
2707pub const sched_param = extern struct {
2708 priority: i32,
2709};
2710
2711pub const SCHED = packed struct(i32) {
2712 pub const Mode = enum(u3) {
2713 /// normal multi-user scheduling
2714 NORMAL = 0,
2715 /// FIFO realtime scheduling
2716 FIFO = 1,
2717 /// Round-robin realtime scheduling
2718 RR = 2,
2719 /// For "batch" style execution of processes
2720 BATCH = 3,
2721 /// Low latency scheduling
2722 IDLE = 5,
2723 /// Sporadic task model deadline scheduling
2724 DEADLINE = 6,
2725 };
2726 mode: Mode, //bits [0, 2]
2727 _3: u27 = 0, //bits [3, 29]
2728 /// set to true to stop children from inheriting policies
2729 RESET_ON_FORK: bool = false, //bit 30
2730 _31: u1 = 0, //bit 31
2731};
2732
2733pub fn sched_setparam(pid: pid_t, param: *const sched_param) usize {
2734 return syscall2(.sched_setparam, @as(u32, @bitCast(pid)), @intFromPtr(param));
2735}
2736
2737pub fn sched_getparam(pid: pid_t, param: *sched_param) usize {
2738 return syscall2(.sched_getparam, @as(u32, @bitCast(pid)), @intFromPtr(param));
2739}
2740
2741pub fn sched_setscheduler(pid: pid_t, policy: SCHED, param: *const sched_param) usize {
2742 return syscall3(.sched_setscheduler, @as(u32, @bitCast(pid)), @as(u32, @bitCast(policy)), @intFromPtr(param));
2743}
2744
2745pub fn sched_getscheduler(pid: pid_t) usize {
2746 return syscall1(.sched_getscheduler, @as(u32, @bitCast(pid)));
2747}
2748
2749pub fn sched_get_priority_max(policy: SCHED) usize {
2750 return syscall1(.sched_get_priority_max, @as(u32, @bitCast(policy)));
2751}
2752
2753pub fn sched_get_priority_min(policy: SCHED) usize {
2754 return syscall1(.sched_get_priority_min, @as(u32, @bitCast(policy)));
2755}
2756
2757pub fn getcpu(cpu: ?*usize, node: ?*usize) usize {
2758 return syscall2(.getcpu, @intFromPtr(cpu), @intFromPtr(node));
2759}
2760
2761pub const sched_attr = extern struct {
2762 size: u32 = 48, // Size of this structure
2763 policy: u32 = 0, // Policy (SCHED_*)
2764 flags: u64 = 0, // Flags
2765 nice: u32 = 0, // Nice value (SCHED_OTHER, SCHED_BATCH)
2766 priority: u32 = 0, // Static priority (SCHED_FIFO, SCHED_RR)
2767 // Remaining fields are for SCHED_DEADLINE
2768 runtime: u64 = 0,
2769 deadline: u64 = 0,
2770 period: u64 = 0,
2771};
2772
2773pub fn sched_setattr(pid: pid_t, attr: *const sched_attr, flags: u32) usize {
2774 return syscall3(.sched_setattr, @as(u32, @bitCast(pid)), @intFromPtr(attr), flags);
2775}
2776
2777pub fn sched_getattr(pid: pid_t, attr: *sched_attr, size: u32, flags: u32) usize {
2778 return syscall4(.sched_getattr, @as(u32, @bitCast(pid)), @intFromPtr(attr), size, flags);
2779}
2780
2781pub fn sched_rr_get_interval(pid: pid_t, tp: *timespec) usize {
2782 return syscall2(.sched_rr_get_interval, @as(u32, @bitCast(pid)), @intFromPtr(tp));
2783}
2784
2785pub fn sched_yield() usize {
2786 return syscall0(.sched_yield);
2787}
2788
2789pub fn sched_getaffinity(pid: pid_t, size: u32, set: *cpu_set_t) usize {
2790 const rc = syscall3(.sched_getaffinity, @as(u32, @bitCast(pid)), size, @intFromPtr(set));
2791 if (@as(isize, @bitCast(rc)) < 0) return rc;
2792 if (rc < size) @memset(@as([*]u8, @ptrCast(set))[rc..size], 0);
2793 return 0;
2794}
2795
2796pub fn sched_setaffinity(pid: pid_t, set: *const cpu_set_t) !void {
2797 const size = @sizeOf(cpu_set_t);
2798 const rc = syscall3(.sched_setaffinity, @as(u32, @bitCast(pid)), size, @intFromPtr(set));
2799
2800 switch (errno(rc)) {
2801 .SUCCESS => return,
2802 else => |err| return std.posix.unexpectedErrno(err),
2803 }
2804}
2805
2806pub fn epoll_create() usize {
2807 return epoll_create1(0);
2808}
2809
2810pub fn epoll_create1(flags: u32) usize {
2811 return syscall1(.epoll_create1, flags);
2812}
2813
2814pub fn epoll_ctl(epoll_fd: fd_t, op: u32, fd: fd_t, ev: ?*epoll_event) usize {
2815 return syscall4(.epoll_ctl, @as(u32, @bitCast(epoll_fd)), op, @as(u32, @bitCast(fd)), @intFromPtr(ev));
2816}
2817
2818pub fn epoll_wait(epoll_fd: fd_t, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
2819 return epoll_pwait(epoll_fd, events, maxevents, timeout, null);
2820}
2821
2822pub fn epoll_pwait(epoll_fd: fd_t, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*const sigset_t) usize {
2823 return syscall6(
2824 .epoll_pwait,
2825 @as(u32, @bitCast(epoll_fd)),
2826 @intFromPtr(events),
2827 maxevents,
2828 @as(u32, @bitCast(timeout)),
2829 @intFromPtr(sigmask),
2830 NSIG / 8,
2831 );
2832}
2833
2834pub fn eventfd(count: u32, flags: u32) usize {
2835 return syscall2(.eventfd2, count, flags);
2836}
2837
2838pub fn timerfd_create(clockid: timerfd_clockid_t, flags: TFD) usize {
2839 return syscall2(
2840 .timerfd_create,
2841 @backingInt(clockid),
2842 @as(u32, @bitCast(flags)),
2843 );
2844}
2845
2846pub const itimerspec = extern struct {
2847 it_interval: timespec,
2848 it_value: timespec,
2849};
2850
2851pub fn timerfd_gettime(fd: fd_t, curr_value: *itimerspec) usize {
2852 return syscall2(
2853 if (@hasField(SYS, "timerfd_gettime") and native_arch != .hexagon) .timerfd_gettime else .timerfd_gettime64,
2854 @as(u32, @bitCast(fd)),
2855 @intFromPtr(curr_value),
2856 );
2857}
2858
2859pub fn timerfd_settime(fd: fd_t, flags: TFD.TIMER, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
2860 return syscall4(
2861 if (@hasField(SYS, "timerfd_settime") and native_arch != .hexagon) .timerfd_settime else .timerfd_settime64,
2862 @as(u32, @bitCast(fd)),
2863 @as(u32, @bitCast(flags)),
2864 @intFromPtr(new_value),
2865 @intFromPtr(old_value),
2866 );
2867}
2868
2869// Flags for the 'setitimer' system call
2870pub const ITIMER = enum(i32) {
2871 REAL = 0,
2872 VIRTUAL = 1,
2873 PROF = 2,
2874};
2875
2876pub fn getitimer(which: i32, curr_value: *itimerspec) usize {
2877 return syscall2(.getitimer, @as(u32, @bitCast(which)), @intFromPtr(curr_value));
2878}
2879
2880pub fn setitimer(which: i32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
2881 return syscall3(.setitimer, @as(u32, @bitCast(which)), @intFromPtr(new_value), @intFromPtr(old_value));
2882}
2883
2884pub fn unshare(flags: usize) usize {
2885 return syscall1(.unshare, flags);
2886}
2887
2888pub fn setns(fd: fd_t, flags: u32) usize {
2889 return syscall2(.setns, @as(u32, @bitCast(fd)), flags);
2890}
2891
2892pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {
2893 return syscall2(.capget, @intFromPtr(hdrp), @intFromPtr(datap));
2894}
2895
2896pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize {
2897 return syscall2(.capset, @intFromPtr(hdrp), @intFromPtr(datap));
2898}
2899
2900pub fn sigaltstack(ss: ?*const stack_t, old_ss: ?*stack_t) usize {
2901 return syscall2(.sigaltstack, @intFromPtr(ss), @intFromPtr(old_ss));
2902}
2903
2904pub fn uname(uts: *utsname) usize {
2905 return syscall1(.uname, @intFromPtr(uts));
2906}
2907
2908pub fn io_uring_setup(entries: u32, p: *io_uring_params) usize {
2909 return syscall2(.io_uring_setup, entries, @intFromPtr(p));
2910}
2911
2912pub fn io_uring_enter(fd: fd_t, to_submit: u32, min_complete: u32, flags: u32, sig: ?*sigset_t) usize {
2913 return syscall6(.io_uring_enter, @as(u32, @bitCast(fd)), to_submit, min_complete, flags, @intFromPtr(sig), NSIG / 8);
2914}
2915
2916pub fn io_uring_register(fd: fd_t, opcode: IORING_REGISTER, arg: ?*const anyopaque, nr_args: u32) usize {
2917 return syscall4(.io_uring_register, @as(u32, @bitCast(fd)), @backingInt(opcode), @intFromPtr(arg), nr_args);
2918}
2919
2920pub fn memfd_create(name: [*:0]const u8, flags: u32) usize {
2921 return syscall2(.memfd_create, @intFromPtr(name), flags);
2922}
2923
2924pub fn getrusage(who: i32, usage: *rusage) usize {
2925 return syscall2(.getrusage, @as(u32, @bitCast(who)), @intFromPtr(usage));
2926}
2927
2928pub fn tcgetattr(fd: fd_t, termios_p: *termios) usize {
2929 return syscall3(.ioctl, @as(u32, @bitCast(fd)), T.CGETS, @intFromPtr(termios_p));
2930}
2931
2932pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usize {
2933 return syscall3(.ioctl, @as(u32, @bitCast(fd)), T.CSETS + @backingInt(optional_action), @intFromPtr(termios_p));
2934}
2935
2936pub fn tcgetpgrp(fd: fd_t, pgrp: *pid_t) usize {
2937 return syscall3(.ioctl, @as(u32, @bitCast(fd)), T.IOCGPGRP, @intFromPtr(pgrp));
2938}
2939
2940pub fn tcsetpgrp(fd: fd_t, pgrp: *const pid_t) usize {
2941 return syscall3(.ioctl, @as(u32, @bitCast(fd)), T.IOCSPGRP, @intFromPtr(pgrp));
2942}
2943
2944pub fn tcdrain(fd: fd_t) usize {
2945 return syscall3(.ioctl, @as(u32, @bitCast(fd)), T.CSBRK, 1);
2946}
2947
2948pub fn ioctl(fd: fd_t, request: u32, arg: usize) usize {
2949 return syscall3(.ioctl, @as(u32, @bitCast(fd)), request, arg);
2950}
2951
2952pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) usize {
2953 return syscall4(.signalfd4, @as(u32, @bitCast(fd)), @intFromPtr(mask), NSIG / 8, flags);
2954}
2955
2956pub fn copy_file_range(fd_in: fd_t, off_in: ?*off_t, fd_out: fd_t, off_out: ?*off_t, len: usize, flags: u32) usize {
2957 return syscall6(
2958 .copy_file_range,
2959 @as(u32, @bitCast(fd_in)),
2960 @intFromPtr(off_in),
2961 @as(u32, @bitCast(fd_out)),
2962 @intFromPtr(off_out),
2963 len,
2964 flags,
2965 );
2966}
2967
2968pub fn bpf(cmd: BPF.Cmd, attr: *BPF.Attr, size: u32) usize {
2969 return syscall3(.bpf, @backingInt(cmd), @intFromPtr(attr), size);
2970}
2971
2972pub fn sync() void {
2973 _ = syscall0(.sync);
2974}
2975
2976pub fn syncfs(fd: fd_t) usize {
2977 return syscall1(.syncfs, @as(u32, @bitCast(fd)));
2978}
2979
2980pub fn fsync(fd: fd_t) usize {
2981 return syscall1(.fsync, @as(u32, @bitCast(fd)));
2982}
2983
2984pub fn fdatasync(fd: fd_t) usize {
2985 return syscall1(.fdatasync, @as(u32, @bitCast(fd)));
2986}
2987
2988pub fn prctl(option: i32, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
2989 return syscall5(.prctl, @as(u32, @bitCast(option)), arg2, arg3, arg4, arg5);
2990}
2991
2992pub fn getrlimit(resource: rlimit_resource, rlim: *rlimit) usize {
2993 // use prlimit64 to have 64 bit limits on 32 bit platforms
2994 return prlimit(0, resource, null, rlim);
2995}
2996
2997pub fn setrlimit(resource: rlimit_resource, rlim: *const rlimit) usize {
2998 // use prlimit64 to have 64 bit limits on 32 bit platforms
2999 return prlimit(0, resource, rlim, null);
3000}
3001
3002pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit, old_limit: ?*rlimit) usize {
3003 return syscall4(
3004 .prlimit64,
3005 @as(u32, @bitCast(pid)),
3006 @as(u32, @bitCast(@as(i32, @backingInt(resource)))),
3007 @intFromPtr(new_limit),
3008 @intFromPtr(old_limit),
3009 );
3010}
3011
3012pub fn mincore(address: [*]u8, len: usize, vec: [*]u8) usize {
3013 return syscall3(.mincore, @intFromPtr(address), len, @intFromPtr(vec));
3014}
3015
3016pub fn madvise(address: [*]u8, len: usize, advice: u32) usize {
3017 return syscall3(.madvise, @intFromPtr(address), len, advice);
3018}
3019
3020pub fn pidfd_open(pid: pid_t, flags: u32) usize {
3021 return syscall2(.pidfd_open, @as(u32, @bitCast(pid)), flags);
3022}
3023
3024pub fn pidfd_getfd(pidfd: fd_t, targetfd: fd_t, flags: u32) usize {
3025 return syscall3(
3026 .pidfd_getfd,
3027 @as(u32, @bitCast(pidfd)),
3028 @as(u32, @bitCast(targetfd)),
3029 flags,
3030 );
3031}
3032
3033pub fn pidfd_send_signal(pidfd: fd_t, sig: SIG, info: ?*siginfo_t, flags: u32) usize {
3034 return syscall4(
3035 .pidfd_send_signal,
3036 @as(u32, @bitCast(pidfd)),
3037 @backingInt(sig),
3038 @intFromPtr(info),
3039 flags,
3040 );
3041}
3042
3043pub fn process_vm_readv(pid: pid_t, local: []const iovec, remote: []const iovec_const, flags: usize) usize {
3044 return syscall6(
3045 .process_vm_readv,
3046 @as(u32, @bitCast(pid)),
3047 @intFromPtr(local.ptr),
3048 local.len,
3049 @intFromPtr(remote.ptr),
3050 remote.len,
3051 flags,
3052 );
3053}
3054
3055pub fn process_vm_writev(pid: pid_t, local: []const iovec_const, remote: []const iovec_const, flags: usize) usize {
3056 return syscall6(
3057 .process_vm_writev,
3058 @as(u32, @bitCast(pid)),
3059 @intFromPtr(local.ptr),
3060 local.len,
3061 @intFromPtr(remote.ptr),
3062 remote.len,
3063 flags,
3064 );
3065}
3066
3067pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize {
3068 if (native_arch.isMIPS32()) {
3069 // MIPS O32 weirdly differs from the other architectures that require
3070 // aligned register pairs for this specific syscall.
3071
3072 const offset_halves = splitValue64(offset);
3073 const length_halves = splitValue64(len);
3074
3075 return syscall7(
3076 .fadvise64,
3077 @as(u32, @bitCast(fd)),
3078 0,
3079 offset_halves[0],
3080 offset_halves[1],
3081 length_halves[0],
3082 length_halves[1],
3083 advice,
3084 );
3085 } else if (require_aligned_register_pair) {
3086 const offset_halves = splitValue64(offset);
3087 const length_halves = splitValue64(len);
3088
3089 return syscall6(
3090 .fadvise64_64,
3091 @as(u32, @bitCast(fd)),
3092 advice,
3093 offset_halves[0],
3094 offset_halves[1],
3095 length_halves[0],
3096 length_halves[1],
3097 );
3098 } else if (@sizeOf(syscall_arg_t) < @sizeOf(u64)) {
3099 const offset_halves = splitValue64(offset);
3100 const length_halves = splitValue64(len);
3101
3102 return syscall6(
3103 .fadvise64_64,
3104 @as(u32, @bitCast(fd)),
3105 offset_halves[0],
3106 offset_halves[1],
3107 length_halves[0],
3108 length_halves[1],
3109 advice,
3110 );
3111 } else {
3112 return syscall4(
3113 .fadvise64,
3114 @as(u32, @bitCast(fd)),
3115 @as(u64, @bitCast(offset)),
3116 @as(u64, @bitCast(len)),
3117 advice,
3118 );
3119 }
3120}
3121
3122pub fn perf_event_open(
3123 attr: *perf_event_attr,
3124 pid: pid_t,
3125 cpu: i32,
3126 group_fd: fd_t,
3127 flags: usize,
3128) usize {
3129 return syscall5(
3130 .perf_event_open,
3131 @intFromPtr(attr),
3132 @as(u32, @bitCast(pid)),
3133 @as(u32, @bitCast(cpu)),
3134 @as(u32, @bitCast(group_fd)),
3135 flags,
3136 );
3137}
3138
3139pub fn seccomp(operation: u32, flags: u32, args: ?*const anyopaque) usize {
3140 return syscall3(.seccomp, operation, flags, @intFromPtr(args));
3141}
3142
3143pub fn ptrace(
3144 req: u32,
3145 pid: pid_t,
3146 addr: usize,
3147 data: usize,
3148 addr2: usize,
3149) usize {
3150 return syscall5(
3151 .ptrace,
3152 req,
3153 @as(u32, @bitCast(pid)),
3154 addr,
3155 data,
3156 addr2,
3157 );
3158}
3159
3160/// Query the page cache statistics of a file.
3161pub fn cachestat(
3162 /// The open file descriptor to retrieve statistics from.
3163 fd: fd_t,
3164 /// The byte range in `fd` to query.
3165 /// When `len > 0`, the range is `[off..off + len]`.
3166 /// When `len` == 0, the range is from `off` to the end of `fd`.
3167 cstat_range: *const cache_stat_range,
3168 /// The structure where page cache statistics are stored.
3169 cstat: *cache_stat,
3170 /// Currently unused, and must be set to `0`.
3171 flags: u32,
3172) usize {
3173 return syscall4(
3174 .cachestat,
3175 @as(u32, @bitCast(fd)),
3176 @intFromPtr(cstat_range),
3177 @intFromPtr(cstat),
3178 flags,
3179 );
3180}
3181
3182pub fn map_shadow_stack(addr: usize, size: usize, flags: u32) usize {
3183 return syscall3(.map_shadow_stack, addr, size, flags);
3184}
3185
3186pub fn tee(src: fd_t, dest: fd_t, len: usize, flags: u32) usize {
3187 return syscall4(
3188 .tee,
3189 @as(u32, @bitCast(src)),
3190 @as(u32, @bitCast(dest)),
3191 len,
3192 flags,
3193 );
3194}
3195
3196pub const Sysinfo = switch (native_abi) {
3197 .gnux32, .muslx32, .x32 => extern struct {
3198 /// Seconds since boot
3199 uptime: i64,
3200 /// 1, 5, and 15 minute load averages
3201 loads: [3]u64,
3202 /// Total usable main memory size
3203 totalram: u64,
3204 /// Available memory size
3205 freeram: u64,
3206 /// Amount of shared memory
3207 sharedram: u64,
3208 /// Memory used by buffers
3209 bufferram: u64,
3210 /// Total swap space size
3211 totalswap: u64,
3212 /// swap space still available
3213 freeswap: u64,
3214 /// Number of current processes
3215 procs: u16,
3216 /// Explicit padding for m68k
3217 pad: u16,
3218 /// Total high memory size
3219 totalhigh: u64,
3220 /// Available high memory size
3221 freehigh: u64,
3222 /// Memory unit size in bytes
3223 mem_unit: u32,
3224 },
3225 else => extern struct {
3226 /// Seconds since boot
3227 uptime: isize,
3228 /// 1, 5, and 15 minute load averages
3229 loads: [3]usize,
3230 /// Total usable main memory size
3231 totalram: usize,
3232 /// Available memory size
3233 freeram: usize,
3234 /// Amount of shared memory
3235 sharedram: usize,
3236 /// Memory used by buffers
3237 bufferram: usize,
3238 /// Total swap space size
3239 totalswap: usize,
3240 /// swap space still available
3241 freeswap: usize,
3242 /// Number of current processes
3243 procs: u16,
3244 /// Explicit padding for m68k
3245 pad: u16,
3246 /// Total high memory size
3247 totalhigh: usize,
3248 /// Available high memory size
3249 freehigh: usize,
3250 /// Memory unit size in bytes
3251 mem_unit: u32,
3252 /// Pad
3253 _f: [20 - 2 * @sizeOf(usize) - @sizeOf(u32)]u8,
3254 },
3255};
3256
3257pub fn sysinfo(info: *Sysinfo) usize {
3258 return syscall1(.sysinfo, @intFromPtr(info));
3259}
3260
3261const VdsoSysRiscvHwprobe = *align(1) const fn (
3262 pairs: [*]riscv_hwprobe,
3263 pair_count: usize,
3264 cpusetsize: usize,
3265 cpus: ?[*]cpu_set_t,
3266 flags: u32,
3267) callconv(.c) usize;
3268var vdso_sys_riscv_hwprobe: ?VdsoSysRiscvHwprobe = &init_vdso_sys_riscv_hwprobe;
3269
3270fn init_vdso_sys_riscv_hwprobe(
3271 pairs: [*]riscv_hwprobe,
3272 pair_count: usize,
3273 cpusetsize: usize,
3274 cpus: ?[*]cpu_set_t,
3275 flags: u32,
3276) callconv(.c) usize {
3277 const ptr: ?VdsoSysRiscvHwprobe = @ptrFromInt(vdso.lookup(VDSO.HWPROBE_VER, VDSO.HWPROBE_SYM));
3278 @atomicStore(?VdsoSysRiscvHwprobe, &vdso_sys_riscv_hwprobe, ptr, .monotonic);
3279 if (ptr) |f| return f(pairs, pair_count, cpusetsize, cpus, flags);
3280 return @bitCast(-@as(isize, @backingInt(E.NOSYS)));
3281}
3282
3283pub fn sys_riscv_hwprobe(
3284 pairs: [*]riscv_hwprobe,
3285 pair_count: usize,
3286 cpusetsize: usize,
3287 cpus: ?[*]cpu_set_t,
3288 flags: u32,
3289) usize {
3290 if (VDSO != void) {
3291 const ptr = @atomicLoad(?VdsoSysRiscvHwprobe, &vdso_sys_riscv_hwprobe, .unordered);
3292 if (ptr) |f| {
3293 if (f(pairs, pair_count, cpusetsize, cpus, flags) == 0) return 0;
3294 }
3295 }
3296 return syscall5(.riscv_hwprobe, @intFromPtr(pairs), pair_count, cpusetsize, @intFromPtr(cpus), flags);
3297}
3298
3299pub const E = switch (native_arch) {
3300 .mips, .mipsel, .mips64, .mips64el => enum(u16) {
3301 /// No error occurred.
3302 SUCCESS = 0,
3303
3304 PERM = 1,
3305 NOENT = 2,
3306 SRCH = 3,
3307 INTR = 4,
3308 IO = 5,
3309 NXIO = 6,
3310 @"2BIG" = 7,
3311 NOEXEC = 8,
3312 BADF = 9,
3313 CHILD = 10,
3314 /// Also used for WOULDBLOCK.
3315 AGAIN = 11,
3316 NOMEM = 12,
3317 ACCES = 13,
3318 FAULT = 14,
3319 NOTBLK = 15,
3320 BUSY = 16,
3321 EXIST = 17,
3322 XDEV = 18,
3323 NODEV = 19,
3324 NOTDIR = 20,
3325 ISDIR = 21,
3326 INVAL = 22,
3327 NFILE = 23,
3328 MFILE = 24,
3329 NOTTY = 25,
3330 TXTBSY = 26,
3331 FBIG = 27,
3332 NOSPC = 28,
3333 SPIPE = 29,
3334 ROFS = 30,
3335 MLINK = 31,
3336 PIPE = 32,
3337 DOM = 33,
3338 RANGE = 34,
3339
3340 NOMSG = 35,
3341 IDRM = 36,
3342 CHRNG = 37,
3343 L2NSYNC = 38,
3344 L3HLT = 39,
3345 L3RST = 40,
3346 LNRNG = 41,
3347 UNATCH = 42,
3348 NOCSI = 43,
3349 L2HLT = 44,
3350 DEADLK = 45,
3351 NOLCK = 46,
3352 BADE = 50,
3353 BADR = 51,
3354 XFULL = 52,
3355 NOANO = 53,
3356 BADRQC = 54,
3357 BADSLT = 55,
3358 DEADLOCK = 56,
3359 BFONT = 59,
3360 NOSTR = 60,
3361 NODATA = 61,
3362 TIME = 62,
3363 NOSR = 63,
3364 NONET = 64,
3365 NOPKG = 65,
3366 REMOTE = 66,
3367 NOLINK = 67,
3368 ADV = 68,
3369 SRMNT = 69,
3370 COMM = 70,
3371 PROTO = 71,
3372 DOTDOT = 73,
3373 MULTIHOP = 74,
3374 BADMSG = 77,
3375 NAMETOOLONG = 78,
3376 OVERFLOW = 79,
3377 NOTUNIQ = 80,
3378 BADFD = 81,
3379 REMCHG = 82,
3380 LIBACC = 83,
3381 LIBBAD = 84,
3382 LIBSCN = 85,
3383 LIBMAX = 86,
3384 LIBEXEC = 87,
3385 ILSEQ = 88,
3386 NOSYS = 89,
3387 LOOP = 90,
3388 RESTART = 91,
3389 STRPIPE = 92,
3390 NOTEMPTY = 93,
3391 USERS = 94,
3392 NOTSOCK = 95,
3393 DESTADDRREQ = 96,
3394 MSGSIZE = 97,
3395 PROTOTYPE = 98,
3396 NOPROTOOPT = 99,
3397 PROTONOSUPPORT = 120,
3398 SOCKTNOSUPPORT = 121,
3399 OPNOTSUPP = 122,
3400 PFNOSUPPORT = 123,
3401 AFNOSUPPORT = 124,
3402 ADDRINUSE = 125,
3403 ADDRNOTAVAIL = 126,
3404 NETDOWN = 127,
3405 NETUNREACH = 128,
3406 NETRESET = 129,
3407 CONNABORTED = 130,
3408 CONNRESET = 131,
3409 NOBUFS = 132,
3410 ISCONN = 133,
3411 NOTCONN = 134,
3412 UCLEAN = 135,
3413 NOTNAM = 137,
3414 NAVAIL = 138,
3415 ISNAM = 139,
3416 REMOTEIO = 140,
3417 SHUTDOWN = 143,
3418 TOOMANYREFS = 144,
3419 TIMEDOUT = 145,
3420 CONNREFUSED = 146,
3421 HOSTDOWN = 147,
3422 HOSTUNREACH = 148,
3423 ALREADY = 149,
3424 INPROGRESS = 150,
3425 STALE = 151,
3426 CANCELED = 158,
3427 NOMEDIUM = 159,
3428 MEDIUMTYPE = 160,
3429 NOKEY = 161,
3430 KEYEXPIRED = 162,
3431 KEYREVOKED = 163,
3432 KEYREJECTED = 164,
3433 OWNERDEAD = 165,
3434 NOTRECOVERABLE = 166,
3435 RFKILL = 167,
3436 HWPOISON = 168,
3437 DQUOT = 1133,
3438 _,
3439 },
3440 .sparc, .sparc64 => enum(u16) {
3441 /// No error occurred.
3442 SUCCESS = 0,
3443
3444 PERM = 1,
3445 NOENT = 2,
3446 SRCH = 3,
3447 INTR = 4,
3448 IO = 5,
3449 NXIO = 6,
3450 @"2BIG" = 7,
3451 NOEXEC = 8,
3452 BADF = 9,
3453 CHILD = 10,
3454 /// Also used for WOULDBLOCK
3455 AGAIN = 11,
3456 NOMEM = 12,
3457 ACCES = 13,
3458 FAULT = 14,
3459 NOTBLK = 15,
3460 BUSY = 16,
3461 EXIST = 17,
3462 XDEV = 18,
3463 NODEV = 19,
3464 NOTDIR = 20,
3465 ISDIR = 21,
3466 INVAL = 22,
3467 NFILE = 23,
3468 MFILE = 24,
3469 NOTTY = 25,
3470 TXTBSY = 26,
3471 FBIG = 27,
3472 NOSPC = 28,
3473 SPIPE = 29,
3474 ROFS = 30,
3475 MLINK = 31,
3476 PIPE = 32,
3477 DOM = 33,
3478 RANGE = 34,
3479
3480 INPROGRESS = 36,
3481 ALREADY = 37,
3482 NOTSOCK = 38,
3483 DESTADDRREQ = 39,
3484 MSGSIZE = 40,
3485 PROTOTYPE = 41,
3486 NOPROTOOPT = 42,
3487 PROTONOSUPPORT = 43,
3488 SOCKTNOSUPPORT = 44,
3489 /// Also used for NOTSUP
3490 OPNOTSUPP = 45,
3491 PFNOSUPPORT = 46,
3492 AFNOSUPPORT = 47,
3493 ADDRINUSE = 48,
3494 ADDRNOTAVAIL = 49,
3495 NETDOWN = 50,
3496 NETUNREACH = 51,
3497 NETRESET = 52,
3498 CONNABORTED = 53,
3499 CONNRESET = 54,
3500 NOBUFS = 55,
3501 ISCONN = 56,
3502 NOTCONN = 57,
3503 SHUTDOWN = 58,
3504 TOOMANYREFS = 59,
3505 TIMEDOUT = 60,
3506 CONNREFUSED = 61,
3507 LOOP = 62,
3508 NAMETOOLONG = 63,
3509 HOSTDOWN = 64,
3510 HOSTUNREACH = 65,
3511 NOTEMPTY = 66,
3512 PROCLIM = 67,
3513 USERS = 68,
3514 DQUOT = 69,
3515 STALE = 70,
3516 REMOTE = 71,
3517 NOSTR = 72,
3518 TIME = 73,
3519 NOSR = 74,
3520 NOMSG = 75,
3521 BADMSG = 76,
3522 IDRM = 77,
3523 DEADLK = 78,
3524 NOLCK = 79,
3525 NONET = 80,
3526 RREMOTE = 81,
3527 NOLINK = 82,
3528 ADV = 83,
3529 SRMNT = 84,
3530 COMM = 85,
3531 PROTO = 86,
3532 MULTIHOP = 87,
3533 DOTDOT = 88,
3534 REMCHG = 89,
3535 NOSYS = 90,
3536 STRPIPE = 91,
3537 OVERFLOW = 92,
3538 BADFD = 93,
3539 CHRNG = 94,
3540 L2NSYNC = 95,
3541 L3HLT = 96,
3542 L3RST = 97,
3543 LNRNG = 98,
3544 UNATCH = 99,
3545 NOCSI = 100,
3546 L2HLT = 101,
3547 BADE = 102,
3548 BADR = 103,
3549 XFULL = 104,
3550 NOANO = 105,
3551 BADRQC = 106,
3552 BADSLT = 107,
3553 DEADLOCK = 108,
3554 BFONT = 109,
3555 LIBEXEC = 110,
3556 NODATA = 111,
3557 LIBBAD = 112,
3558 NOPKG = 113,
3559 LIBACC = 114,
3560 NOTUNIQ = 115,
3561 RESTART = 116,
3562 UCLEAN = 117,
3563 NOTNAM = 118,
3564 NAVAIL = 119,
3565 ISNAM = 120,
3566 REMOTEIO = 121,
3567 ILSEQ = 122,
3568 LIBMAX = 123,
3569 LIBSCN = 124,
3570 NOMEDIUM = 125,
3571 MEDIUMTYPE = 126,
3572 CANCELED = 127,
3573 NOKEY = 128,
3574 KEYEXPIRED = 129,
3575 KEYREVOKED = 130,
3576 KEYREJECTED = 131,
3577 OWNERDEAD = 132,
3578 NOTRECOVERABLE = 133,
3579 RFKILL = 134,
3580 HWPOISON = 135,
3581 _,
3582 },
3583 .alpha => enum(u16) {
3584 /// No error occurred.
3585 SUCCESS = 0,
3586
3587 /// Operation not permitted
3588 PERM = 1,
3589 /// No such file or directory
3590 NOENT = 2,
3591 /// No such process
3592 SRCH = 3,
3593 /// Interrupted system call
3594 INTR = 4,
3595 /// I/O error
3596 IO = 5,
3597 /// No such device or address
3598 NXIO = 6,
3599 /// Argument list too long
3600 @"2BIG" = 7,
3601 /// Exec format error
3602 NOEXEC = 8,
3603 /// Bad file number
3604 BADF = 9,
3605 /// No child processes
3606 CHILD = 10,
3607 /// Out of memory
3608 NOMEM = 12,
3609 /// Permission denied
3610 ACCES = 13,
3611 /// Bad address
3612 FAULT = 14,
3613 /// Block device required
3614 NOTBLK = 15,
3615 /// Device or resource busy
3616 BUSY = 16,
3617 /// File exists
3618 EXIST = 17,
3619 /// Cross-device link
3620 XDEV = 18,
3621 /// No such device
3622 NODEV = 19,
3623 /// Not a directory
3624 NOTDIR = 20,
3625 /// Is a directory
3626 ISDIR = 21,
3627 /// Invalid argument
3628 INVAL = 22,
3629 /// File table overflow
3630 NFILE = 23,
3631 /// Too many open files
3632 MFILE = 24,
3633 /// Not a typewriter
3634 NOTTY = 25,
3635 /// Text file busy
3636 TXTBSY = 26,
3637 /// File too large
3638 FBIG = 27,
3639 /// No space left on device
3640 NOSPC = 28,
3641 /// Illegal seek
3642 SPIPE = 29,
3643 /// Read-only file system
3644 ROFS = 30,
3645 /// Too many links
3646 MLINK = 31,
3647 /// Broken pipe
3648 PIPE = 32,
3649 /// Math argument out of domain of func
3650 DOM = 33,
3651 /// Math result not representable
3652 RANGE = 34,
3653
3654 /// Resource deadlock would occur
3655 DEADLK = 11,
3656
3657 /// Try again.
3658 /// Also used for WOULDBLOCK.
3659 AGAIN = 35,
3660 /// Operation now in progress
3661 INPROGRESS = 36,
3662 /// Operation already in progress
3663 ALREADY = 37,
3664 /// Socket operation on non-socket
3665 NOTSOCK = 38,
3666 /// Destination address required
3667 DESTADDRREQ = 39,
3668 /// Message too long
3669 MSGSIZE = 40,
3670 /// Protocol wrong type for socket
3671 PROTOTYPE = 41,
3672 /// Protocol not available
3673 NOPROTOOPT = 42,
3674 /// Protocol not supported
3675 PROTONOSUPPORT = 43,
3676 /// Socket type not supported
3677 SOCKTNOSUPPORT = 44,
3678 /// Operation not supported on transport endpoint
3679 OPNOTSUPP = 45,
3680 /// Protocol family not supported
3681 PFNOSUPPORT = 46,
3682 /// Address family not supported by protocol
3683 AFNOSUPPORT = 47,
3684 /// Address already in use
3685 ADDRINUSE = 48,
3686 /// Cannot assign requested address
3687 ADDRNOTAVAIL = 49,
3688 /// Network is down
3689 NETDOWN = 50,
3690 /// Network is unreachable
3691 NETUNREACH = 51,
3692 /// Network dropped connection because of reset
3693 NETRESET = 52,
3694 /// Software caused connection abort
3695 CONNABORTED = 53,
3696 /// Connection reset by peer
3697 CONNRESET = 54,
3698 /// No buffer space available
3699 NOBUFS = 55,
3700 /// Transport endpoint is already connected
3701 ISCONN = 56,
3702 /// Transport endpoint is not connected
3703 NOTCONN = 57,
3704 /// Cannot send after transport endpoint shutdown
3705 SHUTDOWN = 58,
3706 /// Too many references: cannot splice
3707 TOOMANYREFS = 59,
3708 /// Connection timed out
3709 TIMEDOUT = 60,
3710 /// Connection refused
3711 CONNREFUSED = 61,
3712 /// Too many symbolic links encountered
3713 LOOP = 62,
3714 /// File name too long
3715 NAMETOOLONG = 63,
3716 /// Host is down
3717 HOSTDOWN = 64,
3718 /// No route to host
3719 HOSTUNREACH = 65,
3720 /// Directory not empty
3721 NOTEMPTY = 66,
3722
3723 /// Too many users
3724 USERS = 68,
3725 /// Quota exceeded
3726 DQUOT = 69,
3727 /// Stale file handle
3728 STALE = 70,
3729 /// Object is remote
3730 REMOTE = 71,
3731
3732 /// No record locks available
3733 NOLCK = 77,
3734 /// Function not implemented
3735 NOSYS = 78,
3736
3737 /// No message of desired type
3738 NOMSG = 80,
3739 /// Identifier removed
3740 IDRM = 81,
3741 /// Out of streams resources
3742 NOSR = 82,
3743 /// Timer expired
3744 TIME = 83,
3745 /// Not a data message
3746 /// Also used for FSBADCRC.
3747 BADMSG = 84,
3748 /// Protocol error
3749 PROTO = 85,
3750 /// No data available
3751 NODATA = 86,
3752 /// Device not a stream
3753 NOSTR = 87,
3754
3755 /// Package not installed
3756 NOPKG = 92,
3757
3758 /// Illegal byte sequence
3759 ILSEQ = 116,
3760
3761 // The following are designated "random noise" by the kernel sources.
3762 /// Channel number out of range
3763 CHRNG = 88,
3764 /// Level 2 not synchronized
3765 L2NSYNC = 89,
3766 /// Level 3 halted
3767 L3HLT = 90,
3768 /// Level 3 reset
3769 L3RST = 91,
3770
3771 /// Link number out of range
3772 LNRNG = 93,
3773 /// Protocol driver not attached
3774 UNATCH = 94,
3775 /// No CSI structure available
3776 NOCSI = 95,
3777 /// Level 2 halted
3778 L2HLT = 96,
3779 /// Invalid exchange
3780 BADE = 97,
3781 /// Invalid request descriptor
3782 BADR = 98,
3783 /// Exchange full
3784 XFULL = 99,
3785 /// No anode
3786 NOANO = 100,
3787 /// Invalid request code
3788 BADRQC = 101,
3789 /// Invalid slot
3790 BADSLT = 102,
3791
3792 /// Bad font file format
3793 BFONT = 104,
3794 /// Machine is not on the network
3795 NONET = 105,
3796 /// Link has been severed
3797 NOLINK = 106,
3798 /// Advertise error
3799 ADV = 107,
3800 /// Srmount error
3801 SRMNT = 108,
3802 /// Communication error on send
3803 COMM = 109,
3804 /// Multihop attempted
3805 MULTIHOP = 110,
3806 /// RFS specific error
3807 DOTDOT = 111,
3808 /// Value too large for defined data type
3809 OVERFLOW = 112,
3810 /// Name not unique on network
3811 NOTUNIQ = 113,
3812 /// File descriptor in bad state
3813 BADFD = 114,
3814 /// Remote address changed
3815 REMCHG = 115,
3816
3817 /// Structure needs cleaning
3818 /// Also used for FSCORRUPTED.
3819 UCLEAN = 117,
3820 /// Not a XENIX named type file
3821 NOTNAM = 118,
3822 /// No XENIX semaphores available
3823 NAVAIL = 119,
3824 /// Is a named type file
3825 ISNAM = 120,
3826 /// Remote I/O error
3827 REMOTEIO = 121,
3828
3829 /// Can not access a needed shared library
3830 LIBACC = 122,
3831 /// Accessing a corrupted shared library
3832 LIBBAD = 123,
3833 /// .lib section in a.out corrupted
3834 LIBSCN = 124,
3835 /// Attempting to link in too many shared libraries
3836 LIBMAX = 125,
3837 /// Cannot exec a shared library directly
3838 LIBEXEC = 126,
3839 /// Interrupted system call should be restarted
3840 RESTART = 127,
3841 /// Streams pipe error
3842 STRPIPE = 128,
3843
3844 /// No medium found
3845 NOMEDIUM = 129,
3846 /// Wrong medium type
3847 MEDIUMTYPE = 130,
3848 /// Operation Cancelled
3849 CANCELED = 131,
3850 /// Required key not available
3851 NOKEY = 132,
3852 /// Key has expired
3853 KEYEXPIRED = 133,
3854 /// Key has been revoked
3855 KEYREVOKED = 134,
3856 /// Key was rejected by service
3857 KEYREJECTED = 135,
3858
3859 // For robust mutexes
3860 /// Owner died
3861 OWNERDEAD = 136,
3862 /// State not recoverable
3863 NOTRECOVERABLE = 137,
3864
3865 /// Operation not possible due to RF-kill
3866 RFKILL = 138,
3867 /// Memory page has hardware error
3868 HWPOISON = 139,
3869 _,
3870 },
3871 else => enum(u16) {
3872 /// No error occurred.
3873 /// Same code used for `NSROK`.
3874 SUCCESS = 0,
3875 /// Operation not permitted
3876 PERM = 1,
3877 /// No such file or directory
3878 NOENT = 2,
3879 /// No such process
3880 SRCH = 3,
3881 /// Interrupted system call
3882 INTR = 4,
3883 /// I/O error
3884 IO = 5,
3885 /// No such device or address
3886 NXIO = 6,
3887 /// Arg list too long
3888 @"2BIG" = 7,
3889 /// Exec format error
3890 NOEXEC = 8,
3891 /// Bad file number
3892 BADF = 9,
3893 /// No child processes
3894 CHILD = 10,
3895 /// Try again
3896 /// Also means: WOULDBLOCK: operation would block
3897 AGAIN = 11,
3898 /// Out of memory
3899 NOMEM = 12,
3900 /// Permission denied
3901 ACCES = 13,
3902 /// Bad address
3903 FAULT = 14,
3904 /// Block device required
3905 NOTBLK = 15,
3906 /// Device or resource busy
3907 BUSY = 16,
3908 /// File exists
3909 EXIST = 17,
3910 /// Cross-device link
3911 XDEV = 18,
3912 /// No such device
3913 NODEV = 19,
3914 /// Not a directory
3915 NOTDIR = 20,
3916 /// Is a directory
3917 ISDIR = 21,
3918 /// Invalid argument
3919 INVAL = 22,
3920 /// File table overflow
3921 NFILE = 23,
3922 /// Too many open files
3923 MFILE = 24,
3924 /// Not a typewriter
3925 NOTTY = 25,
3926 /// Text file busy
3927 TXTBSY = 26,
3928 /// File too large
3929 FBIG = 27,
3930 /// No space left on device
3931 NOSPC = 28,
3932 /// Illegal seek
3933 SPIPE = 29,
3934 /// Read-only file system
3935 ROFS = 30,
3936 /// Too many links
3937 MLINK = 31,
3938 /// Broken pipe
3939 PIPE = 32,
3940 /// Math argument out of domain of func
3941 DOM = 33,
3942 /// Math result not representable
3943 RANGE = 34,
3944 /// Resource deadlock would occur
3945 DEADLK = 35,
3946 /// File name too long
3947 NAMETOOLONG = 36,
3948 /// No record locks available
3949 NOLCK = 37,
3950 /// Function not implemented
3951 NOSYS = 38,
3952 /// Directory not empty
3953 NOTEMPTY = 39,
3954 /// Too many symbolic links encountered
3955 LOOP = 40,
3956 /// No message of desired type
3957 NOMSG = 42,
3958 /// Identifier removed
3959 IDRM = 43,
3960 /// Channel number out of range
3961 CHRNG = 44,
3962 /// Level 2 not synchronized
3963 L2NSYNC = 45,
3964 /// Level 3 halted
3965 L3HLT = 46,
3966 /// Level 3 reset
3967 L3RST = 47,
3968 /// Link number out of range
3969 LNRNG = 48,
3970 /// Protocol driver not attached
3971 UNATCH = 49,
3972 /// No CSI structure available
3973 NOCSI = 50,
3974 /// Level 2 halted
3975 L2HLT = 51,
3976 /// Invalid exchange
3977 BADE = 52,
3978 /// Invalid request descriptor
3979 BADR = 53,
3980 /// Exchange full
3981 XFULL = 54,
3982 /// No anode
3983 NOANO = 55,
3984 /// Invalid request code
3985 BADRQC = 56,
3986 /// Invalid slot
3987 BADSLT = 57,
3988 /// Bad font file format
3989 BFONT = 59,
3990 /// Device not a stream
3991 NOSTR = 60,
3992 /// No data available
3993 NODATA = 61,
3994 /// Timer expired
3995 TIME = 62,
3996 /// Out of streams resources
3997 NOSR = 63,
3998 /// Machine is not on the network
3999 NONET = 64,
4000 /// Package not installed
4001 NOPKG = 65,
4002 /// Object is remote
4003 REMOTE = 66,
4004 /// Link has been severed
4005 NOLINK = 67,
4006 /// Advertise error
4007 ADV = 68,
4008 /// Srmount error
4009 SRMNT = 69,
4010 /// Communication error on send
4011 COMM = 70,
4012 /// Protocol error
4013 PROTO = 71,
4014 /// Multihop attempted
4015 MULTIHOP = 72,
4016 /// RFS specific error
4017 DOTDOT = 73,
4018 /// Not a data message
4019 BADMSG = 74,
4020 /// Value too large for defined data type
4021 OVERFLOW = 75,
4022 /// Name not unique on network
4023 NOTUNIQ = 76,
4024 /// File descriptor in bad state
4025 BADFD = 77,
4026 /// Remote address changed
4027 REMCHG = 78,
4028 /// Can not access a needed shared library
4029 LIBACC = 79,
4030 /// Accessing a corrupted shared library
4031 LIBBAD = 80,
4032 /// .lib section in a.out corrupted
4033 LIBSCN = 81,
4034 /// Attempting to link in too many shared libraries
4035 LIBMAX = 82,
4036 /// Cannot exec a shared library directly
4037 LIBEXEC = 83,
4038 /// Illegal byte sequence
4039 ILSEQ = 84,
4040 /// Interrupted system call should be restarted
4041 RESTART = 85,
4042 /// Streams pipe error
4043 STRPIPE = 86,
4044 /// Too many users
4045 USERS = 87,
4046 /// Socket operation on non-socket
4047 NOTSOCK = 88,
4048 /// Destination address required
4049 DESTADDRREQ = 89,
4050 /// Message too long
4051 MSGSIZE = 90,
4052 /// Protocol wrong type for socket
4053 PROTOTYPE = 91,
4054 /// Protocol not available
4055 NOPROTOOPT = 92,
4056 /// Protocol not supported
4057 PROTONOSUPPORT = 93,
4058 /// Socket type not supported
4059 SOCKTNOSUPPORT = 94,
4060 /// Operation not supported on transport endpoint
4061 /// This code also means `NOTSUP`.
4062 OPNOTSUPP = 95,
4063 /// Protocol family not supported
4064 PFNOSUPPORT = 96,
4065 /// Address family not supported by protocol
4066 AFNOSUPPORT = 97,
4067 /// Address already in use
4068 ADDRINUSE = 98,
4069 /// Cannot assign requested address
4070 ADDRNOTAVAIL = 99,
4071 /// Network is down
4072 NETDOWN = 100,
4073 /// Network is unreachable
4074 NETUNREACH = 101,
4075 /// Network dropped connection because of reset
4076 NETRESET = 102,
4077 /// Software caused connection abort
4078 CONNABORTED = 103,
4079 /// Connection reset by peer
4080 CONNRESET = 104,
4081 /// No buffer space available
4082 NOBUFS = 105,
4083 /// Transport endpoint is already connected
4084 ISCONN = 106,
4085 /// Transport endpoint is not connected
4086 NOTCONN = 107,
4087 /// Cannot send after transport endpoint shutdown
4088 SHUTDOWN = 108,
4089 /// Too many references: cannot splice
4090 TOOMANYREFS = 109,
4091 /// Connection timed out
4092 TIMEDOUT = 110,
4093 /// Connection refused
4094 CONNREFUSED = 111,
4095 /// Host is down
4096 HOSTDOWN = 112,
4097 /// No route to host
4098 HOSTUNREACH = 113,
4099 /// Operation already in progress
4100 ALREADY = 114,
4101 /// Operation now in progress
4102 INPROGRESS = 115,
4103 /// Stale NFS file handle
4104 STALE = 116,
4105 /// Structure needs cleaning
4106 UCLEAN = 117,
4107 /// Not a XENIX named type file
4108 NOTNAM = 118,
4109 /// No XENIX semaphores available
4110 NAVAIL = 119,
4111 /// Is a named type file
4112 ISNAM = 120,
4113 /// Remote I/O error
4114 REMOTEIO = 121,
4115 /// Quota exceeded
4116 DQUOT = 122,
4117 /// No medium found
4118 NOMEDIUM = 123,
4119 /// Wrong medium type
4120 MEDIUMTYPE = 124,
4121 /// Operation canceled
4122 CANCELED = 125,
4123 /// Required key not available
4124 NOKEY = 126,
4125 /// Key has expired
4126 KEYEXPIRED = 127,
4127 /// Key has been revoked
4128 KEYREVOKED = 128,
4129 /// Key was rejected by service
4130 KEYREJECTED = 129,
4131 // for robust mutexes
4132 /// Owner died
4133 OWNERDEAD = 130,
4134 /// State not recoverable
4135 NOTRECOVERABLE = 131,
4136 /// Operation not possible due to RF-kill
4137 RFKILL = 132,
4138 /// Memory page has hardware error
4139 HWPOISON = 133,
4140 // nameserver query return codes
4141 /// DNS server returned answer with no data
4142 NSRNODATA = 160,
4143 /// DNS server claims query was misformatted
4144 NSRFORMERR = 161,
4145 /// DNS server returned general failure
4146 NSRSERVFAIL = 162,
4147 /// Domain name not found
4148 NSRNOTFOUND = 163,
4149 /// DNS server does not implement requested operation
4150 NSRNOTIMP = 164,
4151 /// DNS server refused query
4152 NSRREFUSED = 165,
4153 /// Misformatted DNS query
4154 NSRBADQUERY = 166,
4155 /// Misformatted domain name
4156 NSRBADNAME = 167,
4157 /// Unsupported address family
4158 NSRBADFAMILY = 168,
4159 /// Misformatted DNS reply
4160 NSRBADRESP = 169,
4161 /// Could not contact DNS servers
4162 NSRCONNREFUSED = 170,
4163 /// Timeout while contacting DNS servers
4164 NSRTIMEOUT = 171,
4165 /// End of file
4166 NSROF = 172,
4167 /// Error reading file
4168 NSRFILE = 173,
4169 /// Out of memory
4170 NSRNOMEM = 174,
4171 /// Application terminated lookup
4172 NSRDESTRUCTION = 175,
4173 /// Domain name is too long
4174 NSRQUERYDOMAINTOOLONG = 176,
4175 /// Domain name is too long
4176 NSRCNAMELOOP = 177,
4177
4178 _,
4179 },
4180};
4181
4182pub const NAME_MAX = 255;
4183pub const PATH_MAX = 4096;
4184pub const IOV_MAX = 1024;
4185
4186/// Largest hardware address length
4187/// e.g. a mac address is a type of hardware address
4188pub const MAX_ADDR_LEN = 32;
4189
4190pub const STDIN_FILENO = 0;
4191pub const STDOUT_FILENO = 1;
4192pub const STDERR_FILENO = 2;
4193
4194pub const AT = struct {
4195 /// Special value used to indicate openat should use the current working directory
4196 pub const FDCWD = -100;
4197
4198 /// Do not follow symbolic links
4199 pub const SYMLINK_NOFOLLOW = 0x100;
4200
4201 /// Remove directory instead of unlinking file
4202 pub const REMOVEDIR = 0x200;
4203
4204 /// Follow symbolic links.
4205 pub const SYMLINK_FOLLOW = 0x400;
4206
4207 /// Suppress terminal automount traversal
4208 pub const NO_AUTOMOUNT = 0x800;
4209
4210 /// Allow empty relative pathname
4211 pub const EMPTY_PATH = 0x1000;
4212
4213 /// Type of synchronisation required from statx()
4214 pub const STATX_SYNC_TYPE = 0x6000;
4215
4216 /// - Do whatever stat() does
4217 pub const STATX_SYNC_AS_STAT = 0x0000;
4218
4219 /// - Force the attributes to be sync'd with the server
4220 pub const STATX_FORCE_SYNC = 0x2000;
4221
4222 /// - Don't sync attributes with the server
4223 pub const STATX_DONT_SYNC = 0x4000;
4224
4225 /// Apply to the entire subtree
4226 pub const RECURSIVE = 0x8000;
4227
4228 pub const HANDLE_FID = REMOVEDIR;
4229};
4230
4231pub const FALLOC = struct {
4232 /// Default is extend size
4233 pub const FL_KEEP_SIZE = 0x01;
4234
4235 /// De-allocates range
4236 pub const FL_PUNCH_HOLE = 0x02;
4237
4238 /// Reserved codepoint
4239 pub const FL_NO_HIDE_STALE = 0x04;
4240
4241 /// Removes a range of a file without leaving a hole in the file
4242 pub const FL_COLLAPSE_RANGE = 0x08;
4243
4244 /// Converts a range of file to zeros preferably without issuing data IO
4245 pub const FL_ZERO_RANGE = 0x10;
4246
4247 /// Inserts space within the file size without overwriting any existing data
4248 pub const FL_INSERT_RANGE = 0x20;
4249
4250 /// Unshares shared blocks within the file size without overwriting any existing data
4251 pub const FL_UNSHARE_RANGE = 0x40;
4252};
4253
4254// Futex v1 API commands. See futex man page for each command's
4255// interpretation of the futex arguments.
4256pub const FUTEX_COMMAND = enum(u7) {
4257 WAIT = 0,
4258 WAKE = 1,
4259 FD = 2,
4260 REQUEUE = 3,
4261 CMP_REQUEUE = 4,
4262 WAKE_OP = 5,
4263 LOCK_PI = 6,
4264 UNLOCK_PI = 7,
4265 TRYLOCK_PI = 8,
4266 WAIT_BITSET = 9,
4267 WAKE_BITSET = 10,
4268 WAIT_REQUEUE_PI = 11,
4269 CMP_REQUEUE_PI = 12,
4270};
4271
4272/// Futex v1 API command and flags for the `futex_op` parameter
4273pub const FUTEX_OP = packed struct(u32) {
4274 cmd: FUTEX_COMMAND,
4275 private: bool,
4276 realtime: bool = false, // realtime clock vs. monotonic clock
4277 _reserved: u23 = 0,
4278};
4279
4280/// Futex v1 FUTEX_WAKE_OP `val3` operation:
4281pub const FUTEX_WAKE_OP = packed struct(u32) {
4282 cmd: FUTEX_WAKE_OP_CMD,
4283 /// From C API `FUTEX_OP_ARG_SHIFT`: Use (1 << oparg) as operand
4284 arg_shift: bool = false,
4285 cmp: FUTEX_WAKE_OP_CMP,
4286 oparg: u12,
4287 cmdarg: u12,
4288};
4289
4290/// Futex v1 cmd for FUTEX_WAKE_OP `val3` command.
4291pub const FUTEX_WAKE_OP_CMD = enum(u3) {
4292 /// uaddr2 = oparg
4293 SET = 0,
4294 /// uaddr2 += oparg
4295 ADD = 1,
4296 /// uaddr2 |= oparg
4297 OR = 2,
4298 /// uaddr2 &= ~oparg
4299 ANDN = 3,
4300 /// uaddr2 ^= oparg
4301 XOR = 4,
4302};
4303
4304/// Futex v1 comparison op for FUTEX_WAKE_OP `val3` cmp
4305pub const FUTEX_WAKE_OP_CMP = enum(u4) {
4306 EQ = 0,
4307 NE = 1,
4308 LT = 2,
4309 LE = 3,
4310 GT = 4,
4311 GE = 5,
4312};
4313
4314/// Max numbers of elements in a `futex2_waitone` array.
4315pub const FUTEX2_WAITONE_MAX = 128;
4316
4317/// For futex v2 API, the size of the futex at the uaddr. v1 futex are
4318/// always implicitly U32. As of kernel v6.14, only U32 is implemented
4319/// for v2 futexes.
4320pub const FUTEX2_SIZE = enum(u2) {
4321 U8 = 0,
4322 U16 = 1,
4323 U32 = 2,
4324 U64 = 3,
4325};
4326
4327/// As of kernel 6.14 there are no defined flags to futex2_waitv.
4328pub const FUTEX2_FLAGS_WAITV = packed struct(u32) {
4329 _reserved: u32 = 0,
4330};
4331
4332/// As of kernel 6.14 there are no defined flags to futex2_requeue.
4333pub const FUTEX2_FLAGS_REQUEUE = packed struct(u32) {
4334 _reserved: u32 = 0,
4335};
4336
4337/// Flags for futex v2 APIs (futex2_wait, futex2_wake, futex2_requeue, but
4338/// not the futex2_waitv syscall, but also used in the futex2_waitone struct).
4339pub const FUTEX2_FLAGS = packed struct(u32) {
4340 size: FUTEX2_SIZE,
4341 numa: bool = false,
4342 _reserved: u4 = 0,
4343 private: bool,
4344 _undefined: u24 = 0,
4345};
4346
4347pub const PROT = switch (native_arch) {
4348 .mips, .mipsel, .mips64, .mips64el, .xtensa, .xtensaeb => packed struct(u32) {
4349 READ: bool = false,
4350 WRITE: bool = false,
4351 EXEC: bool = false,
4352 _: u1 = 0,
4353 /// Page may be used for atomic ops.
4354 SEM: bool = false,
4355 __: u19 = 0,
4356 GROWSDOWN: bool = false,
4357 GROWSUP: bool = false,
4358 ___: u6 = 0,
4359 },
4360 else => packed struct(u32) {
4361 READ: bool = false,
4362 WRITE: bool = false,
4363 EXEC: bool = false,
4364 /// Page may be used for atomic ops.
4365 SEM: bool = false,
4366 __: u20 = 0,
4367 GROWSDOWN: bool = false,
4368 GROWSUP: bool = false,
4369 ___: u6 = 0,
4370 },
4371};
4372
4373pub const FD_CLOEXEC = 1;
4374
4375pub const F_OK = 0;
4376pub const X_OK = 1;
4377pub const W_OK = 2;
4378pub const R_OK = 4;
4379
4380pub const W = struct {
4381 pub const NOHANG = 1;
4382 pub const UNTRACED = 2;
4383 pub const STOPPED = 2;
4384 pub const EXITED = 4;
4385 pub const CONTINUED = 8;
4386 pub const NOWAIT = 0x1000000;
4387
4388 pub fn EXITSTATUS(s: u32) u8 {
4389 return @as(u8, @intCast((s & 0xff00) >> 8));
4390 }
4391 pub fn TERMSIG(s: u32) SIG {
4392 return @fromBackingInt(@intCast(s & 0x7f));
4393 }
4394 pub fn STOPSIG(s: u32) SIG {
4395 return @fromBackingInt(@intCast(EXITSTATUS(s)));
4396 }
4397 pub fn IFEXITED(s: u32) bool {
4398 return (s & 0x7f) == 0;
4399 }
4400 pub fn IFSTOPPED(s: u32) bool {
4401 return @as(u16, @truncate(((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
4402 }
4403 pub fn IFSIGNALED(s: u32) bool {
4404 return (s & 0xffff) -% 1 < 0xff;
4405 }
4406};
4407
4408// waitid id types
4409pub const P = enum(c_uint) {
4410 ALL = 0,
4411 PID = 1,
4412 PGID = 2,
4413 PIDFD = 3,
4414 _,
4415};
4416
4417pub const SA = if (is_mips) struct {
4418 pub const NOCLDSTOP = 1;
4419 pub const NOCLDWAIT = 0x10000;
4420 pub const SIGINFO = 8;
4421 pub const RESTART = 0x10000000;
4422 pub const RESETHAND = 0x80000000;
4423 pub const ONSTACK = 0x08000000;
4424 pub const NODEFER = 0x40000000;
4425} else if (is_sparc) struct {
4426 pub const NOCLDSTOP = 0x8;
4427 pub const NOCLDWAIT = 0x100;
4428 pub const SIGINFO = 0x200;
4429 pub const RESTART = 0x2;
4430 pub const RESETHAND = 0x4;
4431 pub const ONSTACK = 0x1;
4432 pub const NODEFER = 0x20;
4433 pub const RESTORER = 0x04000000;
4434} else if (native_arch == .hexagon or is_loongarch or native_arch == .or1k or is_riscv) struct {
4435 pub const NOCLDSTOP = 1;
4436 pub const NOCLDWAIT = 2;
4437 pub const SIGINFO = 4;
4438 pub const RESTART = 0x10000000;
4439 pub const RESETHAND = 0x80000000;
4440 pub const ONSTACK = 0x08000000;
4441 pub const NODEFER = 0x40000000;
4442} else if (native_arch == .alpha) struct {
4443 pub const ONSTACK = 0x00000001;
4444 pub const RESTART = 0x00000002;
4445 pub const NOCLDSTOP = 0x00000004;
4446 pub const NODEFER = 0x00000008;
4447 pub const RESETHAND = 0x00000010;
4448 pub const NOCLDWAIT = 0x00000020;
4449 pub const SIGINFO = 0x00000040;
4450} else struct {
4451 pub const NOCLDSTOP = 1;
4452 pub const NOCLDWAIT = 2;
4453 pub const SIGINFO = 4;
4454 pub const RESTART = 0x10000000;
4455 pub const RESETHAND = 0x80000000;
4456 pub const ONSTACK = 0x08000000;
4457 pub const NODEFER = 0x40000000;
4458 pub const RESTORER = 0x04000000;
4459};
4460
4461pub const SIG = if (is_mips) enum(u32) {
4462 pub const BLOCK = 1;
4463 pub const UNBLOCK = 2;
4464 pub const SETMASK = 3;
4465
4466 pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
4467 pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
4468 pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
4469
4470 pub const IOT: SIG = .ABRT;
4471 pub const POLL: SIG = .IO;
4472
4473 // /arch/mips/include/uapi/asm/signal.h#L25
4474 HUP = 1,
4475 INT = 2,
4476 QUIT = 3,
4477 ILL = 4,
4478 TRAP = 5,
4479 ABRT = 6,
4480 EMT = 7,
4481 FPE = 8,
4482 KILL = 9,
4483 BUS = 10,
4484 SEGV = 11,
4485 SYS = 12,
4486 PIPE = 13,
4487 ALRM = 14,
4488 TERM = 15,
4489 USR1 = 16,
4490 USR2 = 17,
4491 CHLD = 18,
4492 PWR = 19,
4493 WINCH = 20,
4494 URG = 21,
4495 IO = 22,
4496 STOP = 23,
4497 TSTP = 24,
4498 CONT = 25,
4499 TTIN = 26,
4500 TTOU = 27,
4501 VTALRM = 28,
4502 PROF = 29,
4503 XCPU = 30,
4504 XFZ = 31,
4505 _,
4506} else if (is_sparc) enum(u32) {
4507 pub const BLOCK = 1;
4508 pub const UNBLOCK = 2;
4509 pub const SETMASK = 4;
4510
4511 pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
4512 pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
4513 pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
4514
4515 pub const IOT: SIG = .ABRT;
4516 pub const CLD: SIG = .CHLD;
4517 pub const PWR: SIG = .LOST;
4518 pub const POLL: SIG = .IO;
4519
4520 HUP = 1,
4521 INT = 2,
4522 QUIT = 3,
4523 ILL = 4,
4524 TRAP = 5,
4525 ABRT = 6,
4526 EMT = 7,
4527 FPE = 8,
4528 KILL = 9,
4529 BUS = 10,
4530 SEGV = 11,
4531 SYS = 12,
4532 PIPE = 13,
4533 ALRM = 14,
4534 TERM = 15,
4535 URG = 16,
4536 STOP = 17,
4537 TSTP = 18,
4538 CONT = 19,
4539 CHLD = 20,
4540 TTIN = 21,
4541 TTOU = 22,
4542 IO = 23,
4543 XCPU = 24,
4544 XFSZ = 25,
4545 VTALRM = 26,
4546 PROF = 27,
4547 WINCH = 28,
4548 LOST = 29,
4549 USR1 = 30,
4550 USR2 = 31,
4551 _,
4552} else if (native_arch == .alpha) enum(u32) {
4553 pub const BLOCK = 1;
4554 pub const UNBLOCK = 2;
4555 pub const SETMASK = 3;
4556
4557 pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
4558 pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
4559 pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
4560
4561 pub const POLL: SIG = .IO;
4562 pub const PWR: SIG = .INFO;
4563 pub const IOT: SIG = .ABRT;
4564
4565 HUP = 1,
4566 INT = 2,
4567 QUIT = 3,
4568 ILL = 4,
4569 TRAP = 5,
4570 ABRT = 6,
4571 EMT = 7,
4572 FPE = 8,
4573 KILL = 9,
4574 BUS = 10,
4575 SEGV = 11,
4576 SYS = 12,
4577 PIPE = 13,
4578 ALRM = 14,
4579 TERM = 15,
4580 URG = 16,
4581 STOP = 17,
4582 TSTP = 18,
4583 CONT = 19,
4584 CHLD = 20,
4585 TTIN = 21,
4586 TTOU = 22,
4587 IO = 23,
4588 XCPU = 24,
4589 XFSZ = 25,
4590 VTALRM = 26,
4591 PROF = 27,
4592 WINCH = 28,
4593 INFO = 29,
4594 USR1 = 30,
4595 USR2 = 31,
4596 _,
4597} else if (is_hppa) enum(u32) {
4598 pub const BLOCK = 0;
4599 pub const UNBLOCK = 1;
4600 pub const SETMASK = 2;
4601
4602 pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
4603 pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
4604 pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
4605
4606 pub const POLL: SIG = .IO;
4607 pub const IOT: SIG = .ABRT;
4608
4609 HUP = 1,
4610 INT = 2,
4611 QUIT = 3,
4612 ILL = 4,
4613 TRAP = 5,
4614 ABRT = 6,
4615 STKFLT = 7,
4616 FPE = 8,
4617 KILL = 9,
4618 BUS = 10,
4619 SEGV = 11,
4620 XCPU = 12,
4621 PIPE = 13,
4622 ALRM = 14,
4623 TERM = 15,
4624 USR1 = 16,
4625 USR2 = 17,
4626 CHLD = 18,
4627 PWR = 19,
4628 VTALRM = 20,
4629 PROF = 21,
4630 IO = 22,
4631 WINCH = 23,
4632 STOP = 24,
4633 TSTP = 25,
4634 CONT = 26,
4635 TTIN = 27,
4636 TTOU = 28,
4637 URG = 29,
4638 XFSZ = 30,
4639 SYS = 31,
4640 _,
4641} else enum(u32) {
4642 pub const BLOCK = 0;
4643 pub const UNBLOCK = 1;
4644 pub const SETMASK = 2;
4645
4646 pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
4647 pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
4648 pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
4649
4650 pub const POLL: SIG = .IO;
4651 pub const IOT: SIG = .ABRT;
4652
4653 HUP = 1,
4654 INT = 2,
4655 QUIT = 3,
4656 ILL = 4,
4657 TRAP = 5,
4658 ABRT = 6,
4659 BUS = 7,
4660 FPE = 8,
4661 KILL = 9,
4662 USR1 = 10,
4663 SEGV = 11,
4664 USR2 = 12,
4665 PIPE = 13,
4666 ALRM = 14,
4667 TERM = 15,
4668 STKFLT = 16,
4669 CHLD = 17,
4670 CONT = 18,
4671 STOP = 19,
4672 TSTP = 20,
4673 TTIN = 21,
4674 TTOU = 22,
4675 URG = 23,
4676 XCPU = 24,
4677 XFSZ = 25,
4678 VTALRM = 26,
4679 PROF = 27,
4680 WINCH = 28,
4681 IO = 29,
4682 PWR = 30,
4683 SYS = 31,
4684 _,
4685};
4686
4687pub const kernel_rwf = u32;
4688
4689pub const RWF = struct {
4690 pub const HIPRI: kernel_rwf = 0x00000001;
4691 pub const DSYNC: kernel_rwf = 0x00000002;
4692 pub const SYNC: kernel_rwf = 0x00000004;
4693 pub const NOWAIT: kernel_rwf = 0x00000008;
4694 pub const APPEND: kernel_rwf = 0x00000010;
4695};
4696
4697pub const SEEK = struct {
4698 pub const SET = 0;
4699 pub const CUR = 1;
4700 pub const END = 2;
4701};
4702
4703pub const SHUT = struct {
4704 pub const RD = 0;
4705 pub const WR = 1;
4706 pub const RDWR = 2;
4707};
4708
4709pub const SOCK = struct {
4710 pub const STREAM = if (is_mips) 2 else 1;
4711 pub const DGRAM = if (is_mips) 1 else 2;
4712 pub const RAW = 3;
4713 pub const RDM = 4;
4714 pub const SEQPACKET = 5;
4715 pub const DCCP = 6;
4716 pub const PACKET = 10;
4717 pub const CLOEXEC = if (is_sparc)
4718 0o20000000
4719 else if (native_arch == .alpha)
4720 0o10000000
4721 else
4722 0o2000000;
4723 pub const NONBLOCK = if (is_mips)
4724 0o200
4725 else if (is_sparc)
4726 0o40000
4727 else if (is_hppa or native_arch == .alpha)
4728 0x40000000
4729 else
4730 0o4000;
4731};
4732
4733pub const TCP = struct {
4734 /// Turn off Nagle's algorithm
4735 pub const NODELAY = 1;
4736 /// Limit MSS
4737 pub const MAXSEG = 2;
4738 /// Never send partially complete segments.
4739 pub const CORK = 3;
4740 /// Start keeplives after this period, in seconds
4741 pub const KEEPIDLE = 4;
4742 /// Interval between keepalives
4743 pub const KEEPINTVL = 5;
4744 /// Number of keepalives before death
4745 pub const KEEPCNT = 6;
4746 /// Number of SYN retransmits
4747 pub const SYNCNT = 7;
4748 /// Life time of orphaned FIN-WAIT-2 state
4749 pub const LINGER2 = 8;
4750 /// Wake up listener only when data arrive
4751 pub const DEFER_ACCEPT = 9;
4752 /// Bound advertised window
4753 pub const WINDOW_CLAMP = 10;
4754 /// Information about this connection.
4755 pub const INFO = 11;
4756 /// Block/reenable quick acks
4757 pub const QUICKACK = 12;
4758 /// Congestion control algorithm
4759 pub const CONGESTION = 13;
4760 /// TCP MD5 Signature (RFC2385)
4761 pub const MD5SIG = 14;
4762 /// Use linear timeouts for thin streams
4763 pub const THIN_LINEAR_TIMEOUTS = 16;
4764 /// Fast retrans. after 1 dupack
4765 pub const THIN_DUPACK = 17;
4766 /// How long for loss retry before timeout
4767 pub const USER_TIMEOUT = 18;
4768 /// TCP sock is under repair right now
4769 pub const REPAIR = 19;
4770 pub const REPAIR_QUEUE = 20;
4771 pub const QUEUE_SEQ = 21;
4772 pub const REPAIR_OPTIONS = 22;
4773 /// Enable FastOpen on listeners
4774 pub const FASTOPEN = 23;
4775 pub const TIMESTAMP = 24;
4776 /// limit number of unsent bytes in write queue
4777 pub const NOTSENT_LOWAT = 25;
4778 /// Get Congestion Control (optional) info
4779 pub const CC_INFO = 26;
4780 /// Record SYN headers for new connections
4781 pub const SAVE_SYN = 27;
4782 /// Get SYN headers recorded for connection
4783 pub const SAVED_SYN = 28;
4784 /// Get/set window parameters
4785 pub const REPAIR_WINDOW = 29;
4786 /// Attempt FastOpen with connect
4787 pub const FASTOPEN_CONNECT = 30;
4788 /// Attach a ULP to a TCP connection
4789 pub const ULP = 31;
4790 /// TCP MD5 Signature with extensions
4791 pub const MD5SIG_EXT = 32;
4792 /// Set the key for Fast Open (cookie)
4793 pub const FASTOPEN_KEY = 33;
4794 /// Enable TFO without a TFO cookie
4795 pub const FASTOPEN_NO_COOKIE = 34;
4796 pub const ZEROCOPY_RECEIVE = 35;
4797 /// Notify bytes available to read as a cmsg on read
4798 pub const INQ = 36;
4799 pub const CM_INQ = INQ;
4800 /// delay outgoing packets by XX usec
4801 pub const TX_DELAY = 37;
4802
4803 pub const REPAIR_ON = 1;
4804 pub const REPAIR_OFF = 0;
4805 /// Turn off without window probes
4806 pub const REPAIR_OFF_NO_WP = -1;
4807};
4808
4809pub const UDP = struct {
4810 /// Never send partially complete segments
4811 pub const CORK = 1;
4812 /// Set the socket to accept encapsulated packets
4813 pub const ENCAP = 100;
4814 /// Disable sending checksum for UDP6X
4815 pub const NO_CHECK6_TX = 101;
4816 /// Disable accepting checksum for UDP6
4817 pub const NO_CHECK6_RX = 102;
4818 /// Set GSO segmentation size
4819 pub const SEGMENT = 103;
4820 /// This socket can receive UDP GRO packets
4821 pub const GRO = 104;
4822};
4823
4824pub const UDP_ENCAP = struct {
4825 pub const ESPINUDP_NON_IKE = 1;
4826 pub const ESPINUDP = 2;
4827 pub const L2TPINUDP = 3;
4828 pub const GTP0 = 4;
4829 pub const GTP1U = 5;
4830 pub const RXRPC = 6;
4831};
4832
4833pub const PF = struct {
4834 pub const UNSPEC = 0;
4835 pub const LOCAL = 1;
4836 pub const UNIX = LOCAL;
4837 pub const FILE = LOCAL;
4838 pub const INET = 2;
4839 pub const AX25 = 3;
4840 pub const IPX = 4;
4841 pub const APPLETALK = 5;
4842 pub const NETROM = 6;
4843 pub const BRIDGE = 7;
4844 pub const ATMPVC = 8;
4845 pub const X25 = 9;
4846 pub const INET6 = 10;
4847 pub const ROSE = 11;
4848 pub const DECnet = 12;
4849 pub const NETBEUI = 13;
4850 pub const SECURITY = 14;
4851 pub const KEY = 15;
4852 pub const NETLINK = 16;
4853 pub const ROUTE = PF.NETLINK;
4854 pub const PACKET = 17;
4855 pub const ASH = 18;
4856 pub const ECONET = 19;
4857 pub const ATMSVC = 20;
4858 pub const RDS = 21;
4859 pub const SNA = 22;
4860 pub const IRDA = 23;
4861 pub const PPPOX = 24;
4862 pub const WANPIPE = 25;
4863 pub const LLC = 26;
4864 pub const IB = 27;
4865 pub const MPLS = 28;
4866 pub const CAN = 29;
4867 pub const TIPC = 30;
4868 pub const BLUETOOTH = 31;
4869 pub const IUCV = 32;
4870 pub const RXRPC = 33;
4871 pub const ISDN = 34;
4872 pub const PHONET = 35;
4873 pub const IEEE802154 = 36;
4874 pub const CAIF = 37;
4875 pub const ALG = 38;
4876 pub const NFC = 39;
4877 pub const VSOCK = 40;
4878 pub const KCM = 41;
4879 pub const QIPCRTR = 42;
4880 pub const SMC = 43;
4881 pub const XDP = 44;
4882 pub const MAX = 45;
4883};
4884
4885pub const AF = struct {
4886 pub const UNSPEC = PF.UNSPEC;
4887 pub const LOCAL = PF.LOCAL;
4888 pub const UNIX = AF.LOCAL;
4889 pub const FILE = AF.LOCAL;
4890 pub const INET = PF.INET;
4891 pub const AX25 = PF.AX25;
4892 pub const IPX = PF.IPX;
4893 pub const APPLETALK = PF.APPLETALK;
4894 pub const NETROM = PF.NETROM;
4895 pub const BRIDGE = PF.BRIDGE;
4896 pub const ATMPVC = PF.ATMPVC;
4897 pub const X25 = PF.X25;
4898 pub const INET6 = PF.INET6;
4899 pub const ROSE = PF.ROSE;
4900 pub const DECnet = PF.DECnet;
4901 pub const NETBEUI = PF.NETBEUI;
4902 pub const SECURITY = PF.SECURITY;
4903 pub const KEY = PF.KEY;
4904 pub const NETLINK = PF.NETLINK;
4905 pub const ROUTE = PF.ROUTE;
4906 pub const PACKET = PF.PACKET;
4907 pub const ASH = PF.ASH;
4908 pub const ECONET = PF.ECONET;
4909 pub const ATMSVC = PF.ATMSVC;
4910 pub const RDS = PF.RDS;
4911 pub const SNA = PF.SNA;
4912 pub const IRDA = PF.IRDA;
4913 pub const PPPOX = PF.PPPOX;
4914 pub const WANPIPE = PF.WANPIPE;
4915 pub const LLC = PF.LLC;
4916 pub const IB = PF.IB;
4917 pub const MPLS = PF.MPLS;
4918 pub const CAN = PF.CAN;
4919 pub const TIPC = PF.TIPC;
4920 pub const BLUETOOTH = PF.BLUETOOTH;
4921 pub const IUCV = PF.IUCV;
4922 pub const RXRPC = PF.RXRPC;
4923 pub const ISDN = PF.ISDN;
4924 pub const PHONET = PF.PHONET;
4925 pub const IEEE802154 = PF.IEEE802154;
4926 pub const CAIF = PF.CAIF;
4927 pub const ALG = PF.ALG;
4928 pub const NFC = PF.NFC;
4929 pub const VSOCK = PF.VSOCK;
4930 pub const KCM = PF.KCM;
4931 pub const QIPCRTR = PF.QIPCRTR;
4932 pub const SMC = PF.SMC;
4933 pub const XDP = PF.XDP;
4934 pub const MAX = PF.MAX;
4935};
4936
4937pub const SO = if (is_mips) struct {
4938 pub const DEBUG = 1;
4939 pub const REUSEADDR = 0x0004;
4940 pub const KEEPALIVE = 0x0008;
4941 pub const DONTROUTE = 0x0010;
4942 pub const BROADCAST = 0x0020;
4943 pub const LINGER = 0x0080;
4944 pub const OOBINLINE = 0x0100;
4945 pub const REUSEPORT = 0x0200;
4946 pub const SNDBUF = 0x1001;
4947 pub const RCVBUF = 0x1002;
4948 pub const SNDLOWAT = 0x1003;
4949 pub const RCVLOWAT = 0x1004;
4950 pub const RCVTIMEO = 0x1006;
4951 pub const SNDTIMEO = 0x1005;
4952 pub const ERROR = 0x1007;
4953 pub const TYPE = 0x1008;
4954 pub const ACCEPTCONN = 0x1009;
4955 pub const PROTOCOL = 0x1028;
4956 pub const DOMAIN = 0x1029;
4957 pub const NO_CHECK = 11;
4958 pub const PRIORITY = 12;
4959 pub const BSDCOMPAT = 14;
4960 pub const PASSCRED = 17;
4961 pub const PEERCRED = 18;
4962 pub const PEERSEC = 30;
4963 pub const SNDBUFFORCE = 31;
4964 pub const RCVBUFFORCE = 33;
4965 pub const SECURITY_AUTHENTICATION = 22;
4966 pub const SECURITY_ENCRYPTION_TRANSPORT = 23;
4967 pub const SECURITY_ENCRYPTION_NETWORK = 24;
4968 pub const BINDTODEVICE = 25;
4969 pub const ATTACH_FILTER = 26;
4970 pub const DETACH_FILTER = 27;
4971 pub const GET_FILTER = ATTACH_FILTER;
4972 pub const PEERNAME = 28;
4973 pub const TIMESTAMP_OLD = 29;
4974 pub const PASSSEC = 34;
4975 pub const TIMESTAMPNS_OLD = 35;
4976 pub const MARK = 36;
4977 pub const TIMESTAMPING_OLD = 37;
4978 pub const RXQ_OVFL = 40;
4979 pub const WIFI_STATUS = 41;
4980 pub const PEEK_OFF = 42;
4981 pub const NOFCS = 43;
4982 pub const LOCK_FILTER = 44;
4983 pub const SELECT_ERR_QUEUE = 45;
4984 pub const BUSY_POLL = 46;
4985 pub const MAX_PACING_RATE = 47;
4986 pub const BPF_EXTENSIONS = 48;
4987 pub const INCOMING_CPU = 49;
4988 pub const ATTACH_BPF = 50;
4989 pub const DETACH_BPF = DETACH_FILTER;
4990 pub const ATTACH_REUSEPORT_CBPF = 51;
4991 pub const ATTACH_REUSEPORT_EBPF = 52;
4992 pub const CNX_ADVICE = 53;
4993 pub const MEMINFO = 55;
4994 pub const INCOMING_NAPI_ID = 56;
4995 pub const COOKIE = 57;
4996 pub const PEERGROUPS = 59;
4997 pub const ZEROCOPY = 60;
4998 pub const TXTIME = 61;
4999 pub const BINDTOIFINDEX = 62;
5000 pub const TIMESTAMP_NEW = 63;
5001 pub const TIMESTAMPNS_NEW = 64;
5002 pub const TIMESTAMPING_NEW = 65;
5003 pub const RCVTIMEO_NEW = 66;
5004 pub const SNDTIMEO_NEW = 67;
5005 pub const DETACH_REUSEPORT_BPF = 68;
5006} else if (is_ppc) struct {
5007 pub const DEBUG = 1;
5008 pub const REUSEADDR = 2;
5009 pub const TYPE = 3;
5010 pub const ERROR = 4;
5011 pub const DONTROUTE = 5;
5012 pub const BROADCAST = 6;
5013 pub const SNDBUF = 7;
5014 pub const RCVBUF = 8;
5015 pub const KEEPALIVE = 9;
5016 pub const OOBINLINE = 10;
5017 pub const NO_CHECK = 11;
5018 pub const PRIORITY = 12;
5019 pub const LINGER = 13;
5020 pub const BSDCOMPAT = 14;
5021 pub const REUSEPORT = 15;
5022 pub const RCVLOWAT = 16;
5023 pub const SNDLOWAT = 17;
5024 pub const RCVTIMEO = 18;
5025 pub const SNDTIMEO = 19;
5026 pub const PASSCRED = 20;
5027 pub const PEERCRED = 21;
5028 pub const ACCEPTCONN = 30;
5029 pub const PEERSEC = 31;
5030 pub const SNDBUFFORCE = 32;
5031 pub const RCVBUFFORCE = 33;
5032 pub const PROTOCOL = 38;
5033 pub const DOMAIN = 39;
5034 pub const SECURITY_AUTHENTICATION = 22;
5035 pub const SECURITY_ENCRYPTION_TRANSPORT = 23;
5036 pub const SECURITY_ENCRYPTION_NETWORK = 24;
5037 pub const BINDTODEVICE = 25;
5038 pub const ATTACH_FILTER = 26;
5039 pub const DETACH_FILTER = 27;
5040 pub const GET_FILTER = ATTACH_FILTER;
5041 pub const PEERNAME = 28;
5042 pub const TIMESTAMP_OLD = 29;
5043 pub const PASSSEC = 34;
5044 pub const TIMESTAMPNS_OLD = 35;
5045 pub const MARK = 36;
5046 pub const TIMESTAMPING_OLD = 37;
5047 pub const RXQ_OVFL = 40;
5048 pub const WIFI_STATUS = 41;
5049 pub const PEEK_OFF = 42;
5050 pub const NOFCS = 43;
5051 pub const LOCK_FILTER = 44;
5052 pub const SELECT_ERR_QUEUE = 45;
5053 pub const BUSY_POLL = 46;
5054 pub const MAX_PACING_RATE = 47;
5055 pub const BPF_EXTENSIONS = 48;
5056 pub const INCOMING_CPU = 49;
5057 pub const ATTACH_BPF = 50;
5058 pub const DETACH_BPF = DETACH_FILTER;
5059 pub const ATTACH_REUSEPORT_CBPF = 51;
5060 pub const ATTACH_REUSEPORT_EBPF = 52;
5061 pub const CNX_ADVICE = 53;
5062 pub const MEMINFO = 55;
5063 pub const INCOMING_NAPI_ID = 56;
5064 pub const COOKIE = 57;
5065 pub const PEERGROUPS = 59;
5066 pub const ZEROCOPY = 60;
5067 pub const TXTIME = 61;
5068 pub const BINDTOIFINDEX = 62;
5069 pub const TIMESTAMP_NEW = 63;
5070 pub const TIMESTAMPNS_NEW = 64;
5071 pub const TIMESTAMPING_NEW = 65;
5072 pub const RCVTIMEO_NEW = 66;
5073 pub const SNDTIMEO_NEW = 67;
5074 pub const DETACH_REUSEPORT_BPF = 68;
5075} else if (is_sparc) struct {
5076 pub const DEBUG = 1;
5077 pub const REUSEADDR = 4;
5078 pub const TYPE = 4104;
5079 pub const ERROR = 4103;
5080 pub const DONTROUTE = 16;
5081 pub const BROADCAST = 32;
5082 pub const SNDBUF = 4097;
5083 pub const RCVBUF = 4098;
5084 pub const KEEPALIVE = 8;
5085 pub const OOBINLINE = 256;
5086 pub const NO_CHECK = 11;
5087 pub const PRIORITY = 12;
5088 pub const LINGER = 128;
5089 pub const BSDCOMPAT = 1024;
5090 pub const REUSEPORT = 512;
5091 pub const PASSCRED = 2;
5092 pub const PEERCRED = 64;
5093 pub const RCVLOWAT = 2048;
5094 pub const SNDLOWAT = 4096;
5095 pub const RCVTIMEO = 8192;
5096 pub const SNDTIMEO = 16384;
5097 pub const ACCEPTCONN = 32768;
5098 pub const PEERSEC = 30;
5099 pub const SNDBUFFORCE = 4106;
5100 pub const RCVBUFFORCE = 4107;
5101 pub const PROTOCOL = 4136;
5102 pub const DOMAIN = 4137;
5103 pub const SECURITY_AUTHENTICATION = 20481;
5104 pub const SECURITY_ENCRYPTION_TRANSPORT = 20482;
5105 pub const SECURITY_ENCRYPTION_NETWORK = 20484;
5106 pub const BINDTODEVICE = 13;
5107 pub const ATTACH_FILTER = 26;
5108 pub const DETACH_FILTER = 27;
5109 pub const GET_FILTER = 26;
5110 pub const PEERNAME = 28;
5111 pub const TIMESTAMP_OLD = 29;
5112 pub const PASSSEC = 31;
5113 pub const TIMESTAMPNS_OLD = 33;
5114 pub const MARK = 34;
5115 pub const TIMESTAMPING_OLD = 35;
5116 pub const RXQ_OVFL = 36;
5117 pub const WIFI_STATUS = 37;
5118 pub const PEEK_OFF = 38;
5119 pub const NOFCS = 39;
5120 pub const LOCK_FILTER = 40;
5121 pub const SELECT_ERR_QUEUE = 41;
5122 pub const BUSY_POLL = 48;
5123 pub const MAX_PACING_RATE = 49;
5124 pub const BPF_EXTENSIONS = 50;
5125 pub const INCOMING_CPU = 51;
5126 pub const ATTACH_BPF = 52;
5127 pub const DETACH_BPF = 27;
5128 pub const ATTACH_REUSEPORT_CBPF = 53;
5129 pub const ATTACH_REUSEPORT_EBPF = 54;
5130 pub const CNX_ADVICE = 55;
5131 pub const MEMINFO = 57;
5132 pub const INCOMING_NAPI_ID = 58;
5133 pub const COOKIE = 59;
5134 pub const PEERGROUPS = 61;
5135 pub const ZEROCOPY = 62;
5136 pub const TXTIME = 63;
5137 pub const BINDTOIFINDEX = 65;
5138 pub const TIMESTAMP_NEW = 70;
5139 pub const TIMESTAMPNS_NEW = 66;
5140 pub const TIMESTAMPING_NEW = 67;
5141 pub const RCVTIMEO_NEW = 68;
5142 pub const SNDTIMEO_NEW = 69;
5143 pub const DETACH_REUSEPORT_BPF = 71;
5144} else if (native_arch == .alpha) struct {
5145 pub const DEBUG = 1;
5146 pub const REUSEADDR = 0x0004;
5147 pub const KEEPALIVE = 0x0008;
5148 pub const DONTROUTE = 0x0010;
5149 pub const BROADCAST = 0x0020;
5150 pub const LINGER = 0x0080;
5151 pub const OOBINLINE = 0x0100;
5152 pub const REUSEPORT = 0x0200;
5153
5154 pub const SNDBUF = 0x1001;
5155 pub const RCVBUF = 0x1002;
5156 pub const SNDLOWAT = 0x1011;
5157 pub const RCVLOWAT = 0x1010;
5158 pub const RCVTIMEO = 0x1012;
5159 pub const SNDTIMEO = 0x1013;
5160 pub const ERROR = 0x1007;
5161 pub const TYPE = 0x1008;
5162 pub const ACCEPTCONN = 0x1014;
5163 pub const PROTOCOL = 0x1028;
5164 pub const DOMAIN = 0x1029;
5165
5166 pub const NO_CHECK = 11;
5167 pub const PRIORITY = 12;
5168 pub const BSDCOMPAT = 14;
5169 pub const PASSCRED = 17;
5170 pub const PEERCRED = 18;
5171 pub const PEERSEC = 30;
5172 pub const SNDBUFFORCE = 0x100a;
5173 pub const RCVBUFFORCE = 0x100b;
5174 pub const SECURITY_AUTHENTICATION = 19;
5175 pub const SECURITY_ENCRYPTION_TRANSPORT = 20;
5176 pub const SECURITY_ENCRYPTION_NETWORK = 21;
5177 pub const BINDTODEVICE = 25;
5178 pub const ATTACH_FILTER = 26;
5179 pub const DETACH_FILTER = 27;
5180 pub const GET_FILTER = ATTACH_FILTER;
5181 pub const PEERNAME = 28;
5182 pub const TIMESTAMP_OLD = 29;
5183 pub const PASSSEC = 34;
5184 pub const TIMESTAMPNS_OLD = 35;
5185 pub const MARK = 36;
5186 pub const TIMESTAMPING_OLD = 37;
5187 pub const RXQ_OVFL = 40;
5188 pub const WIFI_STATUS = 41;
5189 pub const PEEK_OFF = 42;
5190 pub const NOFCS = 43;
5191 pub const LOCK_FILTER = 44;
5192 pub const SELECT_ERR_QUEUE = 45;
5193 pub const BUSY_POLL = 46;
5194 pub const MAX_PACING_RATE = 47;
5195 pub const BPF_EXTENSIONS = 48;
5196 pub const INCOMING_CPU = 49;
5197 pub const ATTACH_BPF = 50;
5198 pub const DETACH_BPF = DETACH_FILTER;
5199 pub const ATTACH_REUSEPORT_CBPF = 51;
5200 pub const ATTACH_REUSEPORT_EBPF = 52;
5201 pub const CNX_ADVICE = 53;
5202 pub const MEMINFO = 55;
5203 pub const INCOMING_NAPI_ID = 56;
5204 pub const COOKIE = 57;
5205 pub const PEERGROUPS = 59;
5206 pub const ZEROCOPY = 60;
5207 pub const TXTIME = 61;
5208 pub const BINDTOIFINDEX = 62;
5209 pub const TIMESTAMP_NEW = 63;
5210 pub const TIMESTAMPNS_NEW = 64;
5211 pub const TIMESTAMPING_NEW = 65;
5212 pub const RCVTIMEO_NEW = 66;
5213 pub const SNDTIMEO_NEW = 67;
5214 pub const DETACH_REUSEPORT_BPF = 68;
5215} else struct {
5216 pub const DEBUG = 1;
5217 pub const REUSEADDR = 2;
5218 pub const TYPE = 3;
5219 pub const ERROR = 4;
5220 pub const DONTROUTE = 5;
5221 pub const BROADCAST = 6;
5222 pub const SNDBUF = 7;
5223 pub const RCVBUF = 8;
5224 pub const KEEPALIVE = 9;
5225 pub const OOBINLINE = 10;
5226 pub const NO_CHECK = 11;
5227 pub const PRIORITY = 12;
5228 pub const LINGER = 13;
5229 pub const BSDCOMPAT = 14;
5230 pub const REUSEPORT = 15;
5231 pub const PASSCRED = 16;
5232 pub const PEERCRED = 17;
5233 pub const RCVLOWAT = 18;
5234 pub const SNDLOWAT = 19;
5235 pub const RCVTIMEO = 20;
5236 pub const SNDTIMEO = 21;
5237 pub const ACCEPTCONN = 30;
5238 pub const PEERSEC = 31;
5239 pub const SNDBUFFORCE = 32;
5240 pub const RCVBUFFORCE = 33;
5241 pub const PROTOCOL = 38;
5242 pub const DOMAIN = 39;
5243 pub const SECURITY_AUTHENTICATION = 22;
5244 pub const SECURITY_ENCRYPTION_TRANSPORT = 23;
5245 pub const SECURITY_ENCRYPTION_NETWORK = 24;
5246 pub const BINDTODEVICE = 25;
5247 pub const ATTACH_FILTER = 26;
5248 pub const DETACH_FILTER = 27;
5249 pub const GET_FILTER = ATTACH_FILTER;
5250 pub const PEERNAME = 28;
5251 pub const TIMESTAMP_OLD = 29;
5252 pub const PASSSEC = 34;
5253 pub const TIMESTAMPNS_OLD = 35;
5254 pub const MARK = 36;
5255 pub const TIMESTAMPING_OLD = 37;
5256 pub const RXQ_OVFL = 40;
5257 pub const WIFI_STATUS = 41;
5258 pub const PEEK_OFF = 42;
5259 pub const NOFCS = 43;
5260 pub const LOCK_FILTER = 44;
5261 pub const SELECT_ERR_QUEUE = 45;
5262 pub const BUSY_POLL = 46;
5263 pub const MAX_PACING_RATE = 47;
5264 pub const BPF_EXTENSIONS = 48;
5265 pub const INCOMING_CPU = 49;
5266 pub const ATTACH_BPF = 50;
5267 pub const DETACH_BPF = DETACH_FILTER;
5268 pub const ATTACH_REUSEPORT_CBPF = 51;
5269 pub const ATTACH_REUSEPORT_EBPF = 52;
5270 pub const CNX_ADVICE = 53;
5271 pub const MEMINFO = 55;
5272 pub const INCOMING_NAPI_ID = 56;
5273 pub const COOKIE = 57;
5274 pub const PEERGROUPS = 59;
5275 pub const ZEROCOPY = 60;
5276 pub const TXTIME = 61;
5277 pub const BINDTOIFINDEX = 62;
5278 pub const TIMESTAMP_NEW = 63;
5279 pub const TIMESTAMPNS_NEW = 64;
5280 pub const TIMESTAMPING_NEW = 65;
5281 pub const RCVTIMEO_NEW = 66;
5282 pub const SNDTIMEO_NEW = 67;
5283 pub const DETACH_REUSEPORT_BPF = 68;
5284};
5285
5286pub const SCM = struct {
5287 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/socket.h?id=f777d1112ee597d7f7dd3ca232220873a34ad0c8#n178
5288 pub const RIGHTS = 1;
5289 pub const CREDENTIALS = 2;
5290 pub const SECURITY = 3;
5291 pub const PIDFD = 4;
5292
5293 pub const WIFI_STATUS = SO.WIFI_STATUS;
5294 pub const TIMESTAMPING_OPT_STATS = 54;
5295 pub const TIMESTAMPING_PKTINFO = 58;
5296 pub const TXTIME = SO.TXTIME;
5297};
5298
5299pub const SOL = struct {
5300 pub const SOCKET = if (is_mips or is_sparc or native_arch == .alpha)
5301 0xffff
5302 else
5303 1;
5304
5305 pub const IP = 0;
5306 pub const IPV6 = 41;
5307 pub const ICMPV6 = 58;
5308
5309 pub const RAW = 255;
5310 pub const DECNET = 261;
5311 pub const X25 = 262;
5312 pub const PACKET = 263;
5313 pub const ATM = 264;
5314 pub const AAL = 265;
5315 pub const IRDA = 266;
5316 pub const NETBEUI = 267;
5317 pub const LLC = 268;
5318 pub const DCCP = 269;
5319 pub const NETLINK = 270;
5320 pub const TIPC = 271;
5321 pub const RXRPC = 272;
5322 pub const PPPOL2TP = 273;
5323 pub const BLUETOOTH = 274;
5324 pub const PNPIPE = 275;
5325 pub const RDS = 276;
5326 pub const IUCV = 277;
5327 pub const CAIF = 278;
5328 pub const ALG = 279;
5329 pub const NFC = 280;
5330 pub const KCM = 281;
5331 pub const TLS = 282;
5332 pub const XDP = 283;
5333};
5334
5335pub const SOMAXCONN = 128;
5336
5337pub const IP = struct {
5338 pub const TOS = 1;
5339 pub const TTL = 2;
5340 pub const HDRINCL = 3;
5341 pub const OPTIONS = 4;
5342 pub const ROUTER_ALERT = 5;
5343 pub const RECVOPTS = 6;
5344 pub const RETOPTS = 7;
5345 pub const PKTINFO = 8;
5346 pub const PKTOPTIONS = 9;
5347 pub const PMTUDISC = 10;
5348 pub const MTU_DISCOVER = 10;
5349 pub const RECVERR = 11;
5350 pub const RECVTTL = 12;
5351 pub const RECVTOS = 13;
5352 pub const MTU = 14;
5353 pub const FREEBIND = 15;
5354 pub const IPSEC_POLICY = 16;
5355 pub const XFRM_POLICY = 17;
5356 pub const PASSSEC = 18;
5357 pub const TRANSPARENT = 19;
5358 pub const ORIGDSTADDR = 20;
5359 pub const RECVORIGDSTADDR = IP.ORIGDSTADDR;
5360 pub const MINTTL = 21;
5361 pub const NODEFRAG = 22;
5362 pub const CHECKSUM = 23;
5363 pub const BIND_ADDRESS_NO_PORT = 24;
5364 pub const RECVFRAGSIZE = 25;
5365 pub const MULTICAST_IF = 32;
5366 pub const MULTICAST_TTL = 33;
5367 pub const MULTICAST_LOOP = 34;
5368 pub const ADD_MEMBERSHIP = 35;
5369 pub const DROP_MEMBERSHIP = 36;
5370 pub const UNBLOCK_SOURCE = 37;
5371 pub const BLOCK_SOURCE = 38;
5372 pub const ADD_SOURCE_MEMBERSHIP = 39;
5373 pub const DROP_SOURCE_MEMBERSHIP = 40;
5374 pub const MSFILTER = 41;
5375 pub const MULTICAST_ALL = 49;
5376 pub const UNICAST_IF = 50;
5377
5378 pub const RECVRETOPTS = IP.RETOPTS;
5379
5380 pub const PMTUDISC_DONT = 0;
5381 pub const PMTUDISC_WANT = 1;
5382 pub const PMTUDISC_DO = 2;
5383 pub const PMTUDISC_PROBE = 3;
5384 pub const PMTUDISC_INTERFACE = 4;
5385 pub const PMTUDISC_OMIT = 5;
5386
5387 pub const DEFAULT_MULTICAST_TTL = 1;
5388 pub const DEFAULT_MULTICAST_LOOP = 1;
5389 pub const MAX_MEMBERSHIPS = 20;
5390};
5391
5392/// IPv6 socket options
5393pub const IPV6 = struct {
5394 pub const ADDRFORM = 1;
5395 pub const @"2292PKTINFO" = 2;
5396 pub const @"2292HOPOPTS" = 3;
5397 pub const @"2292DSTOPTS" = 4;
5398 pub const @"2292RTHDR" = 5;
5399 pub const @"2292PKTOPTIONS" = 6;
5400 pub const CHECKSUM = 7;
5401 pub const @"2292HOPLIMIT" = 8;
5402 pub const NEXTHOP = 9;
5403 pub const AUTHHDR = 10;
5404 pub const FLOWINFO = 11;
5405
5406 pub const UNICAST_HOPS = 16;
5407 pub const MULTICAST_IF = 17;
5408 pub const MULTICAST_HOPS = 18;
5409 pub const MULTICAST_LOOP = 19;
5410 pub const ADD_MEMBERSHIP = 20;
5411 pub const DROP_MEMBERSHIP = 21;
5412 pub const ROUTER_ALERT = 22;
5413 pub const MTU_DISCOVER = 23;
5414 pub const MTU = 24;
5415 pub const RECVERR = 25;
5416 pub const V6ONLY = 26;
5417 pub const JOIN_ANYCAST = 27;
5418 pub const LEAVE_ANYCAST = 28;
5419
5420 // IPV6.MTU_DISCOVER values
5421 pub const PMTUDISC_DONT = 0;
5422 pub const PMTUDISC_WANT = 1;
5423 pub const PMTUDISC_DO = 2;
5424 pub const PMTUDISC_PROBE = 3;
5425 pub const PMTUDISC_INTERFACE = 4;
5426 pub const PMTUDISC_OMIT = 5;
5427
5428 // Flowlabel
5429 pub const FLOWLABEL_MGR = 32;
5430 pub const FLOWINFO_SEND = 33;
5431 pub const IPSEC_POLICY = 34;
5432 pub const XFRM_POLICY = 35;
5433 pub const HDRINCL = 36;
5434
5435 // Advanced API (RFC3542) (1)
5436 pub const RECVPKTINFO = 49;
5437 pub const PKTINFO = 50;
5438 pub const RECVHOPLIMIT = 51;
5439 pub const HOPLIMIT = 52;
5440 pub const RECVHOPOPTS = 53;
5441 pub const HOPOPTS = 54;
5442 pub const RTHDRDSTOPTS = 55;
5443 pub const RECVRTHDR = 56;
5444 pub const RTHDR = 57;
5445 pub const RECVDSTOPTS = 58;
5446 pub const DSTOPTS = 59;
5447 pub const RECVPATHMTU = 60;
5448 pub const PATHMTU = 61;
5449 pub const DONTFRAG = 62;
5450
5451 // Advanced API (RFC3542) (2)
5452 pub const RECVTCLASS = 66;
5453 pub const TCLASS = 67;
5454
5455 pub const AUTOFLOWLABEL = 70;
5456
5457 // RFC5014: Source address selection
5458 pub const ADDR_PREFERENCES = 72;
5459
5460 pub const PREFER_SRC_TMP = 0x0001;
5461 pub const PREFER_SRC_PUBLIC = 0x0002;
5462 pub const PREFER_SRC_PUBTMP_DEFAULT = 0x0100;
5463 pub const PREFER_SRC_COA = 0x0004;
5464 pub const PREFER_SRC_HOME = 0x0400;
5465 pub const PREFER_SRC_CGA = 0x0008;
5466 pub const PREFER_SRC_NONCGA = 0x0800;
5467
5468 // RFC5082: Generalized Ttl Security Mechanism
5469 pub const MINHOPCOUNT = 73;
5470
5471 pub const ORIGDSTADDR = 74;
5472 pub const RECVORIGDSTADDR = IPV6.ORIGDSTADDR;
5473 pub const TRANSPARENT = 75;
5474 pub const UNICAST_IF = 76;
5475 pub const RECVFRAGSIZE = 77;
5476 pub const FREEBIND = 78;
5477};
5478
5479// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/ip.h?id=64e844505bc08cde3f346f193cbbbab0096fef54#n24
5480pub const IPTOS = struct {
5481 pub const TOS_MASK = 0x1e;
5482 pub fn TOS(t: anytype) @TypeOf(t) {
5483 return t & TOS_MASK;
5484 }
5485
5486 pub const MINCOST = 0x02;
5487 pub const RELIABILITY = 0x04;
5488 pub const THROUGHPUT = 0x08;
5489 pub const LOWDELAY = 0x10;
5490
5491 pub const PREC_MASK = 0xe0;
5492 pub fn PREC(t: anytype) @TypeOf(t) {
5493 return t & PREC_MASK;
5494 }
5495
5496 pub const PREC_ROUTINE = 0x00;
5497 pub const PREC_PRIORITY = 0x20;
5498 pub const PREC_IMMEDIATE = 0x40;
5499 pub const PREC_FLASH = 0x60;
5500 pub const PREC_FLASHOVERRIDE = 0x80;
5501 pub const PREC_CRITIC_ECP = 0xa0;
5502 pub const PREC_INTERNETCONTROL = 0xc0;
5503 pub const PREC_NETCONTROL = 0xe0;
5504};
5505
5506// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/socket.h?id=b1e904999542ad6764eafa54545f1c55776006d1#n43
5507pub const linger = extern struct {
5508 onoff: i32, // non-zero to linger on close
5509 linger: i32, // time to linger in seconds
5510};
5511
5512// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/in.h?id=64e844505bc08cde3f346f193cbbbab0096fef54#n250
5513pub const in_pktinfo = extern struct {
5514 ifindex: i32,
5515 spec_dst: u32,
5516 addr: u32,
5517};
5518
5519// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/ipv6.h?id=f24987ef6959a7efaf79bffd265522c3df18d431#n22
5520pub const in6_pktinfo = extern struct {
5521 addr: [16]u8,
5522 ifindex: i32,
5523};
5524
5525/// IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
5526/// and FCS/CRC (frame check sequence).
5527pub const ETH = struct {
5528 /// Octets in one ethernet addr
5529 pub const ALEN = 6;
5530 /// Octets in ethernet type field
5531 pub const TLEN = 2;
5532 /// Total octets in header
5533 pub const HLEN = 14;
5534 /// Min. octets in frame sans FC
5535 pub const ZLEN = 60;
5536 /// Max. octets in payload
5537 pub const DATA_LEN = 1500;
5538 /// Max. octets in frame sans FCS
5539 pub const FRAME_LEN = 1514;
5540 /// Octets in the FCS
5541 pub const FCS_LEN = 4;
5542
5543 /// Min IPv4 MTU per RFC791
5544 pub const MIN_MTU = 68;
5545 /// 65535, same as IP_MAX_MTU
5546 pub const MAX_MTU = 0xFFFF;
5547
5548 /// These are the defined Ethernet Protocol ID's.
5549 pub const P = struct {
5550 /// Ethernet Loopback packet
5551 pub const LOOP = 0x0060;
5552 /// Xerox PUP packet
5553 pub const PUP = 0x0200;
5554 /// Xerox PUP Addr Trans packet
5555 pub const PUPAT = 0x0201;
5556 /// TSN (IEEE 1722) packet
5557 pub const TSN = 0x22F0;
5558 /// ERSPAN version 2 (type III)
5559 pub const ERSPAN2 = 0x22EB;
5560 /// Internet Protocol packet
5561 pub const IP = 0x0800;
5562 /// CCITT X.25
5563 pub const X25 = 0x0805;
5564 /// Address Resolution packet
5565 pub const ARP = 0x0806;
5566 /// G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ]
5567 pub const BPQ = 0x08FF;
5568 /// Xerox IEEE802.3 PUP packet
5569 pub const IEEEPUP = 0x0a00;
5570 /// Xerox IEEE802.3 PUP Addr Trans packet
5571 pub const IEEEPUPAT = 0x0a01;
5572 /// B.A.T.M.A.N.-Advanced packet [ NOT AN OFFICIALLY REGISTERED ID ]
5573 pub const BATMAN = 0x4305;
5574 /// DEC Assigned proto
5575 pub const DEC = 0x6000;
5576 /// DEC DNA Dump/Load
5577 pub const DNA_DL = 0x6001;
5578 /// DEC DNA Remote Console
5579 pub const DNA_RC = 0x6002;
5580 /// DEC DNA Routing
5581 pub const DNA_RT = 0x6003;
5582 /// DEC LAT
5583 pub const LAT = 0x6004;
5584 /// DEC Diagnostics
5585 pub const DIAG = 0x6005;
5586 /// DEC Customer use
5587 pub const CUST = 0x6006;
5588 /// DEC Systems Comms Arch
5589 pub const SCA = 0x6007;
5590 /// Trans Ether Bridging
5591 pub const TEB = 0x6558;
5592 /// Reverse Addr Res packet
5593 pub const RARP = 0x8035;
5594 /// Appletalk DDP
5595 pub const ATALK = 0x809B;
5596 /// Appletalk AARP
5597 pub const AARP = 0x80F3;
5598 /// 802.1Q VLAN Extended Header
5599 pub const P_8021Q = 0x8100;
5600 /// ERSPAN type II
5601 pub const ERSPAN = 0x88BE;
5602 /// IPX over DIX
5603 pub const IPX = 0x8137;
5604 /// IPv6 over bluebook
5605 pub const IPV6 = 0x86DD;
5606 /// IEEE Pause frames. See 802.3 31B
5607 pub const PAUSE = 0x8808;
5608 /// Slow Protocol. See 802.3ad 43B
5609 pub const SLOW = 0x8809;
5610 /// Web-cache coordination protocol defined in draft-wilson-wrec-wccp-v2-00.txt
5611 pub const WCCP = 0x883E;
5612 /// MPLS Unicast traffic
5613 pub const MPLS_UC = 0x8847;
5614 /// MPLS Multicast traffic
5615 pub const MPLS_MC = 0x8848;
5616 /// MultiProtocol Over ATM
5617 pub const ATMMPOA = 0x884c;
5618 /// PPPoE discovery messages
5619 pub const PPP_DISC = 0x8863;
5620 /// PPPoE session messages
5621 pub const PPP_SES = 0x8864;
5622 /// HPNA, wlan link local tunnel
5623 pub const LINK_CTL = 0x886c;
5624 /// Frame-based ATM Transport over Ethernet
5625 pub const ATMFATE = 0x8884;
5626 /// Port Access Entity (IEEE 802.1X)
5627 pub const PAE = 0x888E;
5628 /// PROFINET
5629 pub const PROFINET = 0x8892;
5630 /// Multiple proprietary protocols
5631 pub const REALTEK = 0x8899;
5632 /// ATA over Ethernet
5633 pub const AOE = 0x88A2;
5634 /// EtherCAT
5635 pub const ETHERCAT = 0x88A4;
5636 /// 802.1ad Service VLAN
5637 pub const @"8021AD" = 0x88A8;
5638 /// 802.1 Local Experimental 1.
5639 pub const @"802_EX1" = 0x88B5;
5640 /// 802.11 Preauthentication
5641 pub const PREAUTH = 0x88C7;
5642 /// TIPC
5643 pub const TIPC = 0x88CA;
5644 /// Link Layer Discovery Protocol
5645 pub const LLDP = 0x88CC;
5646 /// Media Redundancy Protocol
5647 pub const MRP = 0x88E3;
5648 /// 802.1ae MACsec
5649 pub const MACSEC = 0x88E5;
5650 /// 802.1ah Backbone Service Tag
5651 pub const @"8021AH" = 0x88E7;
5652 /// 802.1Q MVRP
5653 pub const MVRP = 0x88F5;
5654 /// IEEE 1588 Timesync
5655 pub const @"1588" = 0x88F7;
5656 /// NCSI protocol
5657 pub const NCSI = 0x88F8;
5658 /// IEC 62439-3 PRP/HSRv0
5659 pub const PRP = 0x88FB;
5660 /// Connectivity Fault Management
5661 pub const CFM = 0x8902;
5662 /// Fibre Channel over Ethernet
5663 pub const FCOE = 0x8906;
5664 /// Infiniband over Ethernet
5665 pub const IBOE = 0x8915;
5666 /// TDLS
5667 pub const TDLS = 0x890D;
5668 /// FCoE Initialization Protocol
5669 pub const FIP = 0x8914;
5670 /// IEEE 802.21 Media Independent Handover Protocol
5671 pub const @"80221" = 0x8917;
5672 /// IEC 62439-3 HSRv1
5673 pub const HSR = 0x892F;
5674 /// Network Service Header
5675 pub const NSH = 0x894F;
5676 /// Ethernet loopback packet, per IEEE 802.3
5677 pub const LOOPBACK = 0x9000;
5678 /// deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ]
5679 pub const QINQ1 = 0x9100;
5680 /// deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ]
5681 pub const QINQ2 = 0x9200;
5682 /// deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ]
5683 pub const QINQ3 = 0x9300;
5684 /// Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ]
5685 pub const EDSA = 0xDADA;
5686 /// Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ]
5687 pub const DSA_8021Q = 0xDADB;
5688 /// A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ]
5689 pub const DSA_A5PSW = 0xE001;
5690 /// ForCES inter-FE LFB type
5691 pub const IFE = 0xED3E;
5692 /// IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ]
5693 pub const AF_IUCV = 0xFBFB;
5694 /// If the value in the ethernet type is more than this value then the frame is Ethernet II. Else it is 802.3
5695 pub const @"802_3_MIN" = 0x0600;
5696
5697 // Non DIX types. Won't clash for 1500 types.
5698
5699 /// Dummy type for 802.3 frames
5700 pub const @"802_3" = 0x0001;
5701 /// Dummy protocol id for AX.25
5702 pub const AX25 = 0x0002;
5703 /// Every packet (be careful!!!)
5704 pub const ALL = 0x0003;
5705 /// 802.2 frames
5706 pub const @"802_2" = 0x0004;
5707 /// Internal only
5708 pub const SNAP = 0x0005;
5709 /// DEC DDCMP: Internal only
5710 pub const DDCMP = 0x0006;
5711 /// Dummy type for WAN PPP frames
5712 pub const WAN_PPP = 0x0007;
5713 /// Dummy type for PPP MP frames
5714 pub const PPP_MP = 0x0008;
5715 /// Localtalk pseudo type
5716 pub const LOCALTALK = 0x0009;
5717 /// CAN: Controller Area Network
5718 pub const CAN = 0x000C;
5719 /// CANFD: CAN flexible data rate
5720 pub const CANFD = 0x000D;
5721 /// CANXL: eXtended frame Length
5722 pub const CANXL = 0x000E;
5723 /// Dummy type for Atalk over PPP
5724 pub const PPPTALK = 0x0010;
5725 /// 802.2 frames
5726 pub const TR_802_2 = 0x0011;
5727 /// Mobitex (kaz@cafe.net)
5728 pub const MOBITEX = 0x0015;
5729 /// Card specific control frames
5730 pub const CONTROL = 0x0016;
5731 /// Linux-IrDA
5732 pub const IRDA = 0x0017;
5733 /// Acorn Econet
5734 pub const ECONET = 0x0018;
5735 /// HDLC frames
5736 pub const HDLC = 0x0019;
5737 /// 1A for ArcNet :-)
5738 pub const ARCNET = 0x001A;
5739 /// Distributed Switch Arch.
5740 pub const DSA = 0x001B;
5741 /// Trailer switch tagging
5742 pub const TRAILER = 0x001C;
5743 /// Nokia Phonet frames
5744 pub const PHONET = 0x00F5;
5745 /// IEEE802.15.4 frame
5746 pub const IEEE802154 = 0x00F6;
5747 /// ST-Ericsson CAIF protocol
5748 pub const CAIF = 0x00F7;
5749 /// Multiplexed DSA protocol
5750 pub const XDSA = 0x00F8;
5751 /// Qualcomm multiplexing and aggregation protocol
5752 pub const MAP = 0x00F9;
5753 /// Management component transport protocol packets
5754 pub const MCTP = 0x00FA;
5755 };
5756};
5757
5758pub const MSG = struct {
5759 pub const OOB = 0x0001;
5760 pub const PEEK = 0x0002;
5761 pub const DONTROUTE = 0x0004;
5762 pub const CTRUNC = 0x0008;
5763 pub const PROXY = 0x0010;
5764 pub const TRUNC = 0x0020;
5765 pub const DONTWAIT = 0x0040;
5766 pub const EOR = 0x0080;
5767 pub const WAITALL = 0x0100;
5768 pub const FIN = 0x0200;
5769 pub const SYN = 0x0400;
5770 pub const CONFIRM = 0x0800;
5771 pub const RST = 0x1000;
5772 pub const ERRQUEUE = 0x2000;
5773 pub const NOSIGNAL = 0x4000;
5774 pub const MORE = 0x8000;
5775 pub const WAITFORONE = 0x10000;
5776 pub const BATCH = 0x40000;
5777 pub const ZEROCOPY = 0x4000000;
5778 pub const FASTOPEN = 0x20000000;
5779 pub const CMSG_CLOEXEC = 0x40000000;
5780};
5781
5782pub const DT = struct {
5783 pub const UNKNOWN = 0;
5784 pub const FIFO = 1;
5785 pub const CHR = 2;
5786 pub const DIR = 4;
5787 pub const BLK = 6;
5788 pub const REG = 8;
5789 pub const LNK = 10;
5790 pub const SOCK = 12;
5791 pub const WHT = 14;
5792};
5793
5794pub const T = if (is_mips) struct {
5795 pub const CGETA = 0x5401;
5796 pub const CSETA = 0x5402;
5797 pub const CSETAW = 0x5403;
5798 pub const CSETAF = 0x5404;
5799
5800 pub const CSBRK = 0x5405;
5801 pub const CXONC = 0x5406;
5802 pub const CFLSH = 0x5407;
5803
5804 pub const CGETS = 0x540d;
5805 pub const CSETS = 0x540e;
5806 pub const CSETSW = 0x540f;
5807 pub const CSETSF = 0x5410;
5808
5809 pub const IOCEXCL = 0x740d;
5810 pub const IOCNXCL = 0x740e;
5811 pub const IOCOUTQ = 0x7472;
5812 pub const IOCSTI = 0x5472;
5813 pub const IOCMGET = 0x741d;
5814 pub const IOCMBIS = 0x741b;
5815 pub const IOCMBIC = 0x741c;
5816 pub const IOCMSET = 0x741a;
5817 pub const IOCPKT = 0x5470;
5818 pub const IOCPKT_DATA = 0x00;
5819 pub const IOCPKT_FLUSHREAD = 0x01;
5820 pub const IOCPKT_FLUSHWRITE = 0x02;
5821 pub const IOCPKT_STOP = 0x04;
5822 pub const IOCPKT_START = 0x08;
5823 pub const IOCPKT_NOSTOP = 0x10;
5824 pub const IOCPKT_DOSTOP = 0x20;
5825 pub const IOCPKT_IOCTL = 0x40;
5826 pub const IOCSWINSZ = IOCTL.IOW('t', 103, winsize);
5827 pub const IOCGWINSZ = IOCTL.IOR('t', 104, winsize);
5828 pub const IOCNOTTY = 0x5471;
5829 pub const IOCSETD = 0x7401;
5830 pub const IOCGETD = 0x7400;
5831
5832 pub const FIOCLEX = 0x6601;
5833 pub const FIONCLEX = 0x6602;
5834 pub const FIOASYNC = 0x667d;
5835 pub const FIONBIO = 0x667e;
5836 pub const FIOQSIZE = 0x667f;
5837
5838 pub const IOCGLTC = 0x7474;
5839 pub const IOCSLTC = 0x7475;
5840 pub const IOCSPGRP = IOCTL.IOW('t', 118, c_int);
5841 pub const IOCGPGRP = IOCTL.IOR('t', 119, c_int);
5842 pub const IOCCONS = IOCTL.IOW('t', 120, c_int);
5843
5844 pub const FIONREAD = 0x467f;
5845 pub const IOCINQ = FIONREAD;
5846
5847 pub const IOCGETP = 0x7408;
5848 pub const IOCSETP = 0x7409;
5849 pub const IOCSETN = 0x740a;
5850
5851 pub const IOCSBRK = 0x5427;
5852 pub const IOCCBRK = 0x5428;
5853 pub const IOCGSID = 0x7416;
5854 pub const CGETS2 = IOCTL.IOR('T', 0x2a, termios2);
5855 pub const CSETS2 = IOCTL.IOW('T', 0x2b, termios2);
5856 pub const CSETSW2 = IOCTL.IOW('T', 0x2c, termios2);
5857 pub const CSETSF2 = IOCTL.IOW('T', 0x2d, termios2);
5858 pub const IOCGRS485 = IOCTL.IOR('T', 0x2e, serial_rs485);
5859 pub const IOCSRS485 = IOCTL.IOWR('T', 0x2f, serial_rs485);
5860 pub const IOCGPTN = IOCTL.IOR('T', 0x30, c_uint);
5861 pub const IOCSPTLCK = IOCTL.IOW('T', 0x31, c_int);
5862 pub const IOCGDEV = IOCTL.IOR('T', 0x32, c_uint);
5863 pub const IOCSIG = IOCTL.IOW('T', 0x36, c_int);
5864 pub const IOCVHANGUP = 0x5437;
5865 pub const IOCGPKT = IOCTL.IOR('T', 0x38, c_int);
5866 pub const IOCGPTLCK = IOCTL.IOR('T', 0x39, c_int);
5867 pub const IOCGEXCL = IOCTL.IOR('T', 0x40, c_int);
5868 pub const IOCGPTPEER = IOCTL.IO('T', 0x41);
5869 pub const IOCGISO7816 = IOCTL.IOR('T', 0x42, serial_iso7816);
5870 pub const IOCSISO7816 = IOCTL.IOWR('T', 0x43, serial_iso7816);
5871
5872 pub const IOCSCTTY = 0x5480;
5873 pub const IOCGSOFTCAR = 0x5481;
5874 pub const IOCSSOFTCAR = 0x5482;
5875 pub const IOCLINUX = 0x5483;
5876 pub const IOCGSERIAL = 0x5484;
5877 pub const IOCSSERIAL = 0x5485;
5878 pub const CSBRKP = 0x5486;
5879 pub const IOCSERCONFIG = 0x5488;
5880 pub const IOCSERGWILD = 0x5489;
5881 pub const IOCSERSWILD = 0x548a;
5882 pub const IOCGLCKTRMIOS = 0x548b;
5883 pub const IOCSLCKTRMIOS = 0x548c;
5884 pub const IOCSERGSTRUCT = 0x548d;
5885 pub const IOCSERGETLSR = 0x548e;
5886 pub const IOCSERGETMULTI = 0x548f;
5887 pub const IOCSERSETMULTI = 0x5490;
5888 pub const IOCMIWAIT = 0x5491;
5889 pub const IOCGICOUNT = 0x5492;
5890} else if (is_ppc or native_arch == .alpha) struct {
5891 pub const FIOCLEX = IOCTL.IO('f', 1);
5892 pub const FIONCLEX = IOCTL.IO('f', 2);
5893 pub const FIOASYNC = IOCTL.IOW('f', 125, c_int);
5894 pub const FIONBIO = IOCTL.IOW('f', 126, c_int);
5895 pub const FIONREAD = IOCTL.IOR('f', 127, c_int);
5896 pub const IOCINQ = FIONREAD;
5897 pub const FIOQSIZE = IOCTL.IOR('f', 128, c_longlong); // loff_t -> __kernel_loff_t -> long long
5898
5899 pub const IOCGETP = IOCTL.IOR('t', 8, sgttyb);
5900 pub const IOCSETP = IOCTL.IOW('t', 9, sgttyb);
5901 pub const IOCSETN = IOCTL.IOW('t', 10, sgttyb);
5902
5903 pub const IOCSETC = IOCTL.IOW('t', 17, tchars);
5904 pub const IOCGETC = IOCTL.IOR('t', 18, tchars);
5905 pub const CGETS = IOCTL.IOR('t', 19, termios);
5906 pub const CSETS = IOCTL.IOW('t', 20, termios);
5907 pub const CSETSW = IOCTL.IOW('t', 21, termios);
5908 pub const CSETSF = IOCTL.IOW('t', 22, termios);
5909
5910 pub const CGETA = IOCTL.IOR('t', 23, termio);
5911 pub const CSETA = IOCTL.IOW('t', 24, termio);
5912 pub const CSETAW = IOCTL.IOW('t', 25, termio);
5913 pub const CSETAF = IOCTL.IOW('t', 28, termio);
5914
5915 pub const CSBRK = IOCTL.IO('t', 29);
5916 pub const CXONC = IOCTL.IO('t', 30);
5917 pub const CFLSH = IOCTL.IO('t', 31);
5918
5919 pub const IOCSWINSZ = IOCTL.IOW('t', 103, winsize);
5920 pub const IOCGWINSZ = IOCTL.IOR('t', 104, winsize);
5921 pub const IOCSTART = IOCTL.IO('t', 110);
5922 pub const IOCSTOP = IOCTL.IO('t', 111);
5923 pub const IOCOUTQ = IOCTL.IOR('t', 115, c_int);
5924
5925 pub const IOCGLTC = IOCTL.IOR('t', 116, ltchars);
5926 pub const IOCSLTC = IOCTL.IOW('t', 117, ltchars);
5927 pub const IOCSPGRP = IOCTL.IOW('t', 118, c_int);
5928 pub const IOCGPGRP = IOCTL.IOR('t', 119, c_int);
5929
5930 pub const IOCEXCL = 0x540c;
5931 pub const IOCNXCL = 0x540d;
5932 pub const IOCSCTTY = 0x540e;
5933
5934 pub const IOCSTI = 0x5412;
5935 pub const IOCMGET = 0x5415;
5936 pub const IOCMBIS = 0x5416;
5937 pub const IOCMBIC = 0x5417;
5938 pub const IOCMSET = 0x5418;
5939 pub const IOCM_LE = 0x001;
5940 pub const IOCM_DTR = 0x002;
5941 pub const IOCM_RTS = 0x004;
5942 pub const IOCM_ST = 0x008;
5943 pub const IOCM_SR = 0x010;
5944 pub const IOCM_CTS = 0x020;
5945 pub const IOCM_CAR = 0x040;
5946 pub const IOCM_RNG = 0x080;
5947 pub const IOCM_DSR = 0x100;
5948 pub const IOCM_CD = IOCM_CAR;
5949 pub const IOCM_RI = IOCM_RNG;
5950 pub const IOCM_OUT1 = 0x2000;
5951 pub const IOCM_OUT2 = 0x4000;
5952 pub const IOCM_LOOP = 0x8000;
5953
5954 pub const IOCGSOFTCAR = 0x5419;
5955 pub const IOCSSOFTCAR = 0x541a;
5956 pub const IOCLINUX = 0x541c;
5957 pub const IOCCONS = 0x541d;
5958 pub const IOCGSERIAL = 0x541e;
5959 pub const IOCSSERIAL = 0x541f;
5960 pub const IOCPKT = 0x5420;
5961 pub const IOCPKT_DATA = 0;
5962 pub const IOCPKT_FLUSHREAD = 1;
5963 pub const IOCPKT_FLUSHWRITE = 2;
5964 pub const IOCPKT_STOP = 4;
5965 pub const IOCPKT_START = 8;
5966 pub const IOCPKT_NOSTOP = 16;
5967 pub const IOCPKT_DOSTOP = 32;
5968 pub const IOCPKT_IOCTL = 64;
5969
5970 pub const IOCNOTTY = 0x5422;
5971 pub const IOCSETD = 0x5423;
5972 pub const IOCGETD = 0x5424;
5973 pub const CSBRKP = 0x5425;
5974 pub const IOCSBRK = 0x5427;
5975 pub const IOCCBRK = 0x5428;
5976 pub const IOCGSID = 0x5429;
5977 pub const IOCGRS485 = 0x542e;
5978 pub const IOCSRS485 = 0x542f;
5979 pub const IOCGPTN = IOCTL.IOR('T', 0x30, c_uint);
5980 pub const IOCSPTLCK = IOCTL.IOW('T', 0x31, c_int);
5981 pub const IOCGDEV = IOCTL.IOR('T', 0x32, c_uint);
5982 pub const IOCSIG = IOCTL.IOW('T', 0x36, c_int);
5983 pub const IOCVHANGUP = 0x5437;
5984 pub const IOCGPKT = IOCTL.IOR('T', 0x38, c_int);
5985 pub const IOCGPTLCK = IOCTL.IOR('T', 0x39, c_int);
5986 pub const IOCGEXCL = IOCTL.IOR('T', 0x40, c_int);
5987 pub const IOCGPTPEER = IOCTL.IO('T', 0x41);
5988 pub const IOCGISO7816 = IOCTL.IOR('T', 0x42, serial_iso7816);
5989 pub const IOCSISO7816 = IOCTL.IOWR('T', 0x43, serial_iso7816);
5990
5991 pub const IOCSERCONFIG = 0x5453;
5992 pub const IOCSERGWILD = 0x5454;
5993 pub const IOCSERSWILD = 0x5455;
5994 pub const IOCGLCKTRMIOS = 0x5456;
5995 pub const IOCSLCKTRMIOS = 0x5457;
5996 pub const IOCSERGSTRUCT = 0x5458;
5997 pub const IOCSERGETLSR = 0x5459;
5998 pub const IOCSER_TEMT = 0x01;
5999 pub const IOCSERGETMULTI = 0x545a;
6000 pub const IOCSERSETMULTI = 0x545b;
6001
6002 pub const IOCMIWAIT = 0x545c;
6003 pub const IOCGICOUNT = 0x545d;
6004} else if (is_sparc) struct {
6005 // Entries with double-underscore prefix have not been translated as they are unsupported.
6006
6007 pub const CGETA = IOCTL.IOR('T', 1, termio);
6008 pub const CSETA = IOCTL.IOW('T', 2, termio);
6009 pub const CSETAW = IOCTL.IOW('T', 3, termio);
6010 pub const CSETAF = IOCTL.IOW('T', 4, termio);
6011 pub const CSBRK = IOCTL.IO('T', 5);
6012 pub const CXONC = IOCTL.IO('T', 6);
6013 pub const CFLSH = IOCTL.IO('T', 7);
6014 pub const CGETS = IOCTL.IOR('T', 8, termios);
6015 pub const CSETS = IOCTL.IOW('T', 9, termios);
6016 pub const CSETSW = IOCTL.IOW('T', 10, termios);
6017 pub const CSETSF = IOCTL.IOW('T', 11, termios);
6018 pub const CGETS2 = IOCTL.IOR('T', 12, termios2);
6019 pub const CSETS2 = IOCTL.IOW('T', 13, termios2);
6020 pub const CSETSW2 = IOCTL.IOW('T', 14, termios2);
6021 pub const CSETSF2 = IOCTL.IOW('T', 15, termios2);
6022 pub const IOCGDEV = IOCTL.IOR('T', 0x32, c_uint);
6023 pub const IOCVHANGUP = IOCTL.IO('T', 0x37);
6024 pub const IOCGPKT = IOCTL.IOR('T', 0x38, c_int);
6025 pub const IOCGPTLCK = IOCTL.IOR('T', 0x39, c_int);
6026 pub const IOCGEXCL = IOCTL.IOR('T', 0x40, c_int);
6027 pub const IOCGRS485 = IOCTL.IOR('T', 0x41, serial_rs485);
6028 pub const IOCSRS485 = IOCTL.IOWR('T', 0x42, serial_rs485);
6029 pub const IOCGISO7816 = IOCTL.IOR('T', 0x43, serial_iso7816);
6030 pub const IOCSISO7816 = IOCTL.IOWR('T', 0x44, serial_iso7816);
6031
6032 pub const IOCGETD = IOCTL.IOR('t', 0, c_int);
6033 pub const IOCSETD = IOCTL.IOW('t', 1, c_int);
6034 pub const IOCEXCL = IOCTL.IO('t', 13);
6035 pub const IOCNXCL = IOCTL.IO('t', 14);
6036 pub const IOCCONS = IOCTL.IO('t', 36);
6037 pub const IOCGSOFTCAR = IOCTL.IOR('t', 100, c_int);
6038 pub const IOCSSOFTCAR = IOCTL.IOW('t', 101, c_int);
6039 pub const IOCSWINSZ = IOCTL.IOW('t', 103, winsize);
6040 pub const IOCGWINSZ = IOCTL.IOR('t', 104, winsize);
6041 pub const IOCMGET = IOCTL.IOR('t', 106, c_int);
6042 pub const IOCMBIC = IOCTL.IOW('t', 107, c_int);
6043 pub const IOCMBIS = IOCTL.IOW('t', 108, c_int);
6044 pub const IOCMSET = IOCTL.IOW('t', 109, c_int);
6045 pub const IOCSTART = IOCTL.IO('t', 110);
6046 pub const IOCSTOP = IOCTL.IO('t', 111);
6047 pub const IOCPKT = IOCTL.IOW('t', 112, c_int);
6048 pub const IOCNOTTY = IOCTL.IO('t', 113);
6049 pub const IOCSTI = IOCTL.IOW('t', 114, c_char);
6050 pub const IOCOUTQ = IOCTL.IOR('t', 115, c_int);
6051 pub const IOCCBRK = IOCTL.IO('t', 122);
6052 pub const IOCSBRK = IOCTL.IO('t', 123);
6053 pub const IOCSPGRP = IOCTL.IOW('t', 130, c_int);
6054 pub const IOCGPGRP = IOCTL.IOR('t', 131, c_int);
6055 pub const IOCSCTTY = IOCTL.IO('t', 132);
6056 pub const IOCGSID = IOCTL.IOR('t', 133, c_int);
6057 pub const IOCGPTN = IOCTL.IOR('t', 134, c_uint);
6058 pub const IOCSPTLCK = IOCTL.IOW('t', 135, c_int);
6059 pub const IOCSIG = IOCTL.IOW('t', 136, c_int);
6060 pub const IOCGPTPEER = IOCTL.IO('t', 137);
6061
6062 pub const FIOCLEX = IOCTL.IO('f', 1);
6063 pub const FIONCLEX = IOCTL.IO('f', 2);
6064 pub const FIOASYNC = IOCTL.IOW('f', 125, c_int);
6065 pub const FIONBIO = IOCTL.IOW('f', 126, c_int);
6066 pub const FIONREAD = IOCTL.IOR('f', 127, c_int);
6067 pub const IOCINQ = FIONREAD;
6068 pub const FIOQSIZE = IOCTL.IOR('f', 128, c_longlong); // loff_t -> __kernel_loff_t -> long long
6069
6070 pub const IOCLINUX = 0x541c;
6071 pub const IOCGSERIAL = 0x541e;
6072 pub const IOCSSERIAL = 0x541f;
6073 pub const CSBRKP = 0x5425;
6074 pub const IOCSERCONFIG = 0x5453;
6075 pub const IOCSERGWILD = 0x5454;
6076 pub const IOCSERSWILD = 0x5455;
6077 pub const IOCGLCKTRMIOS = 0x5456;
6078 pub const IOCSLCKTRMIOS = 0x5457;
6079 pub const IOCSERGSTRUCT = 0x5458;
6080 pub const IOCSERGETLSR = 0x5459;
6081 pub const IOCSERGETMULTI = 0x545a;
6082 pub const IOCSERSETMULTI = 0x545b;
6083 pub const IOCMIWAIT = 0x545c;
6084 pub const IOCGICOUNT = 0x545d;
6085
6086 pub const IOCPKT_DATA = 0;
6087 pub const IOCPKT_FLUSHREAD = 1;
6088 pub const IOCPKT_FLUSHWRITE = 2;
6089 pub const IOCPKT_STOP = 4;
6090 pub const IOCPKT_START = 8;
6091 pub const IOCPKT_NOSTOP = 16;
6092 pub const IOCPKT_DOSTOP = 32;
6093 pub const IOCPKT_IOCTL = 64;
6094} else struct {
6095 pub const CGETS = 0x5401;
6096 pub const CSETS = 0x5402;
6097 pub const CSETSW = 0x5403;
6098 pub const CSETSF = 0x5404;
6099 pub const CGETA = 0x5405;
6100 pub const CSETA = 0x5406;
6101 pub const CSETAW = 0x5407;
6102 pub const CSETAF = 0x5408;
6103 pub const CSBRK = 0x5409;
6104 pub const CXONC = 0x540a;
6105 pub const CFLSH = 0x540b;
6106 pub const IOCEXCL = 0x540c;
6107 pub const IOCNXCL = 0x540d;
6108 pub const IOCSCTTY = 0x540e;
6109 pub const IOCGPGRP = 0x540f;
6110 pub const IOCSPGRP = 0x5410;
6111 pub const IOCOUTQ = 0x5411;
6112 pub const IOCSTI = 0x5412;
6113 pub const IOCGWINSZ = 0x5413;
6114 pub const IOCSWINSZ = 0x5414;
6115 pub const IOCMGET = 0x5415;
6116 pub const IOCMBIS = 0x5416;
6117 pub const IOCMBIC = 0x5417;
6118 pub const IOCMSET = 0x5418;
6119 pub const IOCGSOFTCAR = 0x5419;
6120 pub const IOCSSOFTCAR = 0x541a;
6121 pub const FIONREAD = 0x541b;
6122 pub const IOCINQ = FIONREAD;
6123 pub const IOCLINUX = 0x541c;
6124 pub const IOCCONS = 0x541d;
6125 pub const IOCGSERIAL = 0x541e;
6126 pub const IOCSSERIAL = 0x541f;
6127 pub const IOCPKT = 0x5420;
6128 pub const FIONBIO = 0x5421;
6129 pub const IOCNOTTY = 0x5422;
6130 pub const IOCSETD = 0x5423;
6131 pub const IOCGETD = 0x5424;
6132 pub const CSBRKP = 0x5425;
6133 pub const IOCSBRK = 0x5427;
6134 pub const IOCCBRK = 0x5428;
6135 pub const IOCGSID = 0x5429;
6136 pub const CGETS2 = IOCTL.IOR('T', 0x2a, termios2);
6137 pub const CSETS2 = IOCTL.IOW('T', 0x2b, termios2);
6138 pub const CSETSW2 = IOCTL.IOW('T', 0x2c, termios2);
6139 pub const CSETSF2 = IOCTL.IOW('T', 0x2d, termios2);
6140 pub const IOCGRS485 = 0x542e;
6141 pub const IOCSRS485 = 0x542f;
6142 pub const IOCGPTN = IOCTL.IOR('T', 0x30, c_uint);
6143 pub const IOCSPTLCK = IOCTL.IOW('T', 0x31, c_int);
6144 pub const IOCGDEV = IOCTL.IOR('T', 0x32, c_uint);
6145 pub const CGETX = 0x5432;
6146 pub const CSETX = 0x5433;
6147 pub const CSETXF = 0x5434;
6148 pub const CSETXW = 0x5435;
6149 pub const IOCSIG = IOCTL.IOW('T', 0x36, c_int);
6150 pub const IOCVHANGUP = 0x5437;
6151 pub const IOCGPKT = IOCTL.IOR('T', 0x38, c_int);
6152 pub const IOCGPTLCK = IOCTL.IOR('T', 0x39, c_int);
6153 pub const IOCGEXCL = IOCTL.IOR('T', 0x40, c_int);
6154 pub const IOCGPTPEER = IOCTL.IO('T', 0x41);
6155 pub const IOCGISO7816 = IOCTL.IOR('T', 0x42, serial_iso7816);
6156 pub const IOCSISO7816 = IOCTL.IOWR('T', 0x43, serial_iso7816);
6157
6158 pub const FIONCLEX = 0x5450;
6159 pub const FIOCLEX = 0x5451;
6160 pub const FIOASYNC = 0x5452;
6161 pub const IOCSERCONFIG = 0x5453;
6162 pub const IOCSERGWILD = 0x5454;
6163 pub const IOCSERSWILD = 0x5455;
6164 pub const IOCGLCKTRMIOS = 0x5456;
6165 pub const IOCSLCKTRMIOS = 0x5457;
6166 pub const IOCSERGSTRUCT = 0x5458;
6167 pub const IOCSERGETLSR = 0x5459;
6168 pub const IOCSERGETMULTI = 0x545a;
6169 pub const IOCSERSETMULTI = 0x545b;
6170
6171 pub const IOCMIWAIT = 0x545c;
6172 pub const IOCGICOUNT = 0x545d;
6173
6174 pub const FIOQSIZE = switch (native_arch) {
6175 .arm,
6176 .armeb,
6177 .thumb,
6178 .thumbeb,
6179 .m68k,
6180 .s390x,
6181 => 0x545e,
6182 else => 0x5460,
6183 };
6184
6185 pub const IOCPKT_DATA = 0;
6186 pub const IOCPKT_FLUSHREAD = 1;
6187 pub const IOCPKT_FLUSHWRITE = 2;
6188 pub const IOCPKT_STOP = 4;
6189 pub const IOCPKT_START = 8;
6190 pub const IOCPKT_NOSTOP = 16;
6191 pub const IOCPKT_DOSTOP = 32;
6192 pub const IOCPKT_IOCTL = 64;
6193
6194 pub const IOCSER_TEMT = 0x01;
6195};
6196
6197pub const serial_rs485 = extern struct {
6198 flags: u32,
6199 delay_rts_before_send: u32,
6200 delay_rts_after_send: u32,
6201 extra: extern union {
6202 _pad1: [5]u32,
6203 s: extern struct {
6204 addr_recv: u8,
6205 addr_dest: u8,
6206 _pad2: [2]u8,
6207 _pad3: [4]u32,
6208 },
6209 },
6210};
6211
6212pub const serial_iso7816 = extern struct {
6213 flags: u32,
6214 tg: u32,
6215 sc_fi: u32,
6216 sc_di: u32,
6217 clk: u32,
6218 _reserved: [5]u32,
6219};
6220
6221pub const SER = struct {
6222 pub const RS485 = struct {
6223 pub const ENABLED = 1 << 0;
6224 pub const RTS_ON_SEND = 1 << 1;
6225 pub const RTS_AFTER_SEND = 1 << 2;
6226 pub const RX_DURING_TX = 1 << 4;
6227 pub const TERMINATE_BUS = 1 << 5;
6228 pub const ADDRB = 1 << 6;
6229 pub const ADDR_RECV = 1 << 7;
6230 pub const ADDR_DEST = 1 << 8;
6231 };
6232
6233 pub const ISO7816 = struct {
6234 pub const ENABLED = 1 << 0;
6235 pub const T_PARAM = 0x0f << 4;
6236
6237 pub fn T(t: anytype) @TypeOf(t) {
6238 return (t & 0x0f) << 4;
6239 }
6240 };
6241};
6242
6243pub const EPOLL = struct {
6244 pub const CLOEXEC = 1 << @bitOffsetOf(O, "CLOEXEC");
6245
6246 pub const CTL_ADD = 1;
6247 pub const CTL_DEL = 2;
6248 pub const CTL_MOD = 3;
6249
6250 pub const IN = 0x001;
6251 pub const PRI = 0x002;
6252 pub const OUT = 0x004;
6253 pub const RDNORM = 0x040;
6254 pub const RDBAND = 0x080;
6255 pub const WRNORM = if (is_mips) 0x004 else 0x100;
6256 pub const WRBAND = if (is_mips) 0x100 else 0x200;
6257 pub const MSG = 0x400;
6258 pub const ERR = 0x008;
6259 pub const HUP = 0x010;
6260 pub const RDHUP = 0x2000;
6261 pub const EXCLUSIVE = (@as(u32, 1) << 28);
6262 pub const WAKEUP = (@as(u32, 1) << 29);
6263 pub const ONESHOT = (@as(u32, 1) << 30);
6264 pub const ET = (@as(u32, 1) << 31);
6265};
6266
6267pub const CLOCK = clockid_t;
6268
6269pub const clockid_t = enum(u32) {
6270 REALTIME = 0,
6271 MONOTONIC = 1,
6272 PROCESS_CPUTIME_ID = 2,
6273 THREAD_CPUTIME_ID = 3,
6274 MONOTONIC_RAW = 4,
6275 REALTIME_COARSE = 5,
6276 MONOTONIC_COARSE = 6,
6277 BOOTTIME = 7,
6278 REALTIME_ALARM = 8,
6279 BOOTTIME_ALARM = 9,
6280 // In the linux kernel header file (time.h) is the following note:
6281 // * The driver implementing this got removed. The clock ID is kept as a
6282 // * place holder. Do not reuse!
6283 // Therefore, calling clock_gettime() with these IDs will result in an error.
6284 //
6285 // Some backgrond:
6286 // - SGI_CYCLE was for Silicon Graphics (SGI) workstations,
6287 // which are probably no longer in use, so it makes sense to disable
6288 // - TAI_CLOCK was designed as CLOCK_REALTIME(UTC) + tai_offset,
6289 // but tai_offset was always 0 in the kernel.
6290 // So there is no point in using this clock.
6291 // SGI_CYCLE = 10,
6292 // TAI = 11,
6293 _,
6294};
6295
6296// For use with posix.timerfd_create()
6297// Actually, the parameter for the timerfd_create() function is in integer,
6298// which means that the developer has to figure out which value is appropriate.
6299// To make this easier and, above all, safer, because an incorrect value leads
6300// to a panic, an enum is introduced which only allows the values
6301// that actually work.
6302pub const TIMERFD_CLOCK = timerfd_clockid_t;
6303pub const timerfd_clockid_t = enum(u32) {
6304 REALTIME = 0,
6305 MONOTONIC = 1,
6306 BOOTTIME = 7,
6307 REALTIME_ALARM = 8,
6308 BOOTTIME_ALARM = 9,
6309 _,
6310};
6311
6312pub const TIMER = packed struct(u32) {
6313 ABSTIME: bool,
6314 _: u31 = 0,
6315};
6316
6317pub const CSIGNAL = 0x000000ff;
6318
6319pub const CLONE = struct {
6320 pub const VM = 0x00000100;
6321 pub const FS = 0x00000200;
6322 pub const FILES = 0x00000400;
6323 pub const SIGHAND = 0x00000800;
6324 pub const PIDFD = 0x00001000;
6325 pub const PTRACE = 0x00002000;
6326 pub const VFORK = 0x00004000;
6327 pub const PARENT = 0x00008000;
6328 pub const THREAD = 0x00010000;
6329 pub const NEWNS = 0x00020000;
6330 pub const SYSVSEM = 0x00040000;
6331 pub const SETTLS = 0x00080000;
6332 pub const PARENT_SETTID = 0x00100000;
6333 pub const CHILD_CLEARTID = 0x00200000;
6334 pub const DETACHED = 0x00400000;
6335 pub const UNTRACED = 0x00800000;
6336 pub const CHILD_SETTID = 0x01000000;
6337 pub const NEWCGROUP = 0x02000000;
6338 pub const NEWUTS = 0x04000000;
6339 pub const NEWIPC = 0x08000000;
6340 pub const NEWUSER = 0x10000000;
6341 pub const NEWPID = 0x20000000;
6342 pub const NEWNET = 0x40000000;
6343 pub const IO = 0x80000000;
6344
6345 // Flags for the clone3() syscall.
6346
6347 /// Clear any signal handler and reset to SIG_DFL.
6348 pub const CLEAR_SIGHAND = 0x100000000;
6349 /// Clone into a specific cgroup given the right permissions.
6350 pub const INTO_CGROUP = 0x200000000;
6351
6352 // cloning flags intersect with CSIGNAL so can be used with unshare and clone3 syscalls only.
6353
6354 /// New time namespace
6355 pub const NEWTIME = 0x00000080;
6356};
6357
6358pub const EFD = struct {
6359 pub const SEMAPHORE = 1;
6360 pub const CLOEXEC = 1 << @bitOffsetOf(O, "CLOEXEC");
6361 pub const NONBLOCK = 1 << @bitOffsetOf(O, "NONBLOCK");
6362};
6363
6364pub const MS = struct {
6365 pub const RDONLY = 1;
6366 pub const NOSUID = 2;
6367 pub const NODEV = 4;
6368 pub const NOEXEC = 8;
6369 pub const SYNCHRONOUS = 16;
6370 pub const REMOUNT = 32;
6371 pub const MANDLOCK = 64;
6372 pub const DIRSYNC = 128;
6373 pub const NOATIME = 1024;
6374 pub const NODIRATIME = 2048;
6375 pub const BIND = 4096;
6376 pub const MOVE = 8192;
6377 pub const REC = 16384;
6378 pub const SILENT = 32768;
6379 pub const POSIXACL = (1 << 16);
6380 pub const UNBINDABLE = (1 << 17);
6381 pub const PRIVATE = (1 << 18);
6382 pub const SLAVE = (1 << 19);
6383 pub const SHARED = (1 << 20);
6384 pub const RELATIME = (1 << 21);
6385 pub const KERNMOUNT = (1 << 22);
6386 pub const I_VERSION = (1 << 23);
6387 pub const STRICTATIME = (1 << 24);
6388 pub const LAZYTIME = (1 << 25);
6389 pub const NOREMOTELOCK = (1 << 27);
6390 pub const NOSEC = (1 << 28);
6391 pub const BORN = (1 << 29);
6392 pub const ACTIVE = (1 << 30);
6393 pub const NOUSER = (1 << 31);
6394
6395 pub const RMT_MASK = (RDONLY | SYNCHRONOUS | MANDLOCK | I_VERSION | LAZYTIME);
6396
6397 pub const MGC_VAL = 0xc0ed0000;
6398 pub const MGC_MSK = 0xffff0000;
6399};
6400
6401pub const MNT = struct {
6402 pub const FORCE = 1;
6403 pub const DETACH = 2;
6404 pub const EXPIRE = 4;
6405};
6406
6407pub const UMOUNT_NOFOLLOW = 8;
6408
6409pub const IN = struct {
6410 pub const CLOEXEC = 1 << @bitOffsetOf(O, "CLOEXEC");
6411 pub const NONBLOCK = 1 << @bitOffsetOf(O, "NONBLOCK");
6412
6413 pub const ACCESS = 0x00000001;
6414 pub const MODIFY = 0x00000002;
6415 pub const ATTRIB = 0x00000004;
6416 pub const CLOSE_WRITE = 0x00000008;
6417 pub const CLOSE_NOWRITE = 0x00000010;
6418 pub const CLOSE = CLOSE_WRITE | CLOSE_NOWRITE;
6419 pub const OPEN = 0x00000020;
6420 pub const MOVED_FROM = 0x00000040;
6421 pub const MOVED_TO = 0x00000080;
6422 pub const MOVE = MOVED_FROM | MOVED_TO;
6423 pub const CREATE = 0x00000100;
6424 pub const DELETE = 0x00000200;
6425 pub const DELETE_SELF = 0x00000400;
6426 pub const MOVE_SELF = 0x00000800;
6427 pub const ALL_EVENTS = 0x00000fff;
6428
6429 pub const UNMOUNT = 0x00002000;
6430 pub const Q_OVERFLOW = 0x00004000;
6431 pub const IGNORED = 0x00008000;
6432
6433 pub const ONLYDIR = 0x01000000;
6434 pub const DONT_FOLLOW = 0x02000000;
6435 pub const EXCL_UNLINK = 0x04000000;
6436 pub const MASK_CREATE = 0x10000000;
6437 pub const MASK_ADD = 0x20000000;
6438
6439 pub const ISDIR = 0x40000000;
6440 pub const ONESHOT = 0x80000000;
6441};
6442
6443pub const fanotify = struct {
6444 pub const InitFlags = packed struct(u32) {
6445 CLOEXEC: bool = false,
6446 NONBLOCK: bool = false,
6447 CLASS: enum(u2) {
6448 NOTIF = 0,
6449 CONTENT = 1,
6450 PRE_CONTENT = 2,
6451 } = .NOTIF,
6452 UNLIMITED_QUEUE: bool = false,
6453 UNLIMITED_MARKS: bool = false,
6454 ENABLE_AUDIT: bool = false,
6455 REPORT_PIDFD: bool = false,
6456 REPORT_TID: bool = false,
6457 REPORT_FID: bool = false,
6458 REPORT_DIR_FID: bool = false,
6459 REPORT_NAME: bool = false,
6460 REPORT_TARGET_FID: bool = false,
6461 _: u19 = 0,
6462 };
6463
6464 pub const MarkFlags = packed struct(u32) {
6465 ADD: bool = false,
6466 REMOVE: bool = false,
6467 DONT_FOLLOW: bool = false,
6468 ONLYDIR: bool = false,
6469 MOUNT: bool = false,
6470 /// Mutually exclusive with `IGNORE`
6471 IGNORED_MASK: bool = false,
6472 IGNORED_SURV_MODIFY: bool = false,
6473 FLUSH: bool = false,
6474 FILESYSTEM: bool = false,
6475 EVICTABLE: bool = false,
6476 /// Mutually exclusive with `IGNORED_MASK`
6477 IGNORE: bool = false,
6478 _: u21 = 0,
6479 };
6480
6481 pub const MarkMask = packed struct(u64) {
6482 /// File was accessed
6483 ACCESS: bool = false,
6484 /// File was modified
6485 MODIFY: bool = false,
6486 /// Metadata changed
6487 ATTRIB: bool = false,
6488 /// Writtable file closed
6489 CLOSE_WRITE: bool = false,
6490 /// Unwrittable file closed
6491 CLOSE_NOWRITE: bool = false,
6492 /// File was opened
6493 OPEN: bool = false,
6494 /// File was moved from X
6495 MOVED_FROM: bool = false,
6496 /// File was moved to Y
6497 MOVED_TO: bool = false,
6498
6499 /// Subfile was created
6500 CREATE: bool = false,
6501 /// Subfile was deleted
6502 DELETE: bool = false,
6503 /// Self was deleted
6504 DELETE_SELF: bool = false,
6505 /// Self was moved
6506 MOVE_SELF: bool = false,
6507 /// File was opened for exec
6508 OPEN_EXEC: bool = false,
6509 reserved13: u1 = 0,
6510 /// Event queued overflowed
6511 Q_OVERFLOW: bool = false,
6512 /// Filesystem error
6513 FS_ERROR: bool = false,
6514
6515 /// File open in perm check
6516 OPEN_PERM: bool = false,
6517 /// File accessed in perm check
6518 ACCESS_PERM: bool = false,
6519 /// File open/exec in perm check
6520 OPEN_EXEC_PERM: bool = false,
6521 reserved19: u8 = 0,
6522 /// Interested in child events
6523 EVENT_ON_CHILD: bool = false,
6524 /// File was renamed
6525 RENAME: bool = false,
6526 reserved30: u1 = 0,
6527 /// Event occurred against dir
6528 ONDIR: bool = false,
6529 reserved31: u33 = 0,
6530 };
6531
6532 pub const event_metadata = extern struct {
6533 event_len: u32,
6534 vers: u8,
6535 reserved: u8,
6536 metadata_len: u16,
6537 mask: MarkMask align(8),
6538 fd: i32,
6539 pid: i32,
6540
6541 pub const VERSION = 3;
6542 };
6543
6544 pub const response = extern struct {
6545 fd: i32,
6546 response: u32,
6547 };
6548
6549 /// Unique file identifier info record.
6550 ///
6551 /// This structure is used for records of types `EVENT_INFO_TYPE.FID`.
6552 /// `EVENT_INFO_TYPE.DFID` and `EVENT_INFO_TYPE.DFID_NAME`.
6553 ///
6554 /// For `EVENT_INFO_TYPE.DFID_NAME` there is additionally a null terminated
6555 /// name immediately after the file handle.
6556 pub const event_info_fid = extern struct {
6557 hdr: event_info_header,
6558 fsid: kernel_fsid_t,
6559 /// Following is an opaque struct file_handle that can be passed as
6560 /// an argument to open_by_handle_at(2).
6561 handle: [0]u8,
6562 };
6563
6564 /// Variable length info record following event metadata.
6565 pub const event_info_header = extern struct {
6566 info_type: EVENT_INFO_TYPE,
6567 pad: u8,
6568 len: u16,
6569 };
6570
6571 pub const EVENT_INFO_TYPE = enum(u8) {
6572 FID = 1,
6573 DFID_NAME = 2,
6574 DFID = 3,
6575 PIDFD = 4,
6576 ERROR = 5,
6577 OLD_DFID_NAME = 10,
6578 OLD_DFID = 11,
6579 NEW_DFID_NAME = 12,
6580 NEW_DFID = 13,
6581 };
6582};
6583
6584pub const file_handle = extern struct {
6585 handle_bytes: u32,
6586 handle_type: i32,
6587 f_handle: [0]u8,
6588};
6589
6590pub const kernel_fsid_t = fsid_t;
6591pub const fsid_t = [2]i32;
6592
6593pub const S = struct {
6594 pub const IFMT = 0o170000;
6595
6596 pub const IFDIR = 0o040000;
6597 pub const IFCHR = 0o020000;
6598 pub const IFBLK = 0o060000;
6599 pub const IFREG = 0o100000;
6600 pub const IFIFO = 0o010000;
6601 pub const IFLNK = 0o120000;
6602 pub const IFSOCK = 0o140000;
6603
6604 pub const ISUID = 0o4000;
6605 pub const ISGID = 0o2000;
6606 pub const ISVTX = 0o1000;
6607 pub const IRUSR = 0o400;
6608 pub const IWUSR = 0o200;
6609 pub const IXUSR = 0o100;
6610 pub const IRWXU = 0o700;
6611 pub const IRGRP = 0o040;
6612 pub const IWGRP = 0o020;
6613 pub const IXGRP = 0o010;
6614 pub const IRWXG = 0o070;
6615 pub const IROTH = 0o004;
6616 pub const IWOTH = 0o002;
6617 pub const IXOTH = 0o001;
6618 pub const IRWXO = 0o007;
6619
6620 pub fn ISREG(m: mode_t) bool {
6621 return m & IFMT == IFREG;
6622 }
6623
6624 pub fn ISDIR(m: mode_t) bool {
6625 return m & IFMT == IFDIR;
6626 }
6627
6628 pub fn ISCHR(m: mode_t) bool {
6629 return m & IFMT == IFCHR;
6630 }
6631
6632 pub fn ISBLK(m: mode_t) bool {
6633 return m & IFMT == IFBLK;
6634 }
6635
6636 pub fn ISFIFO(m: mode_t) bool {
6637 return m & IFMT == IFIFO;
6638 }
6639
6640 pub fn ISLNK(m: mode_t) bool {
6641 return m & IFMT == IFLNK;
6642 }
6643
6644 pub fn ISSOCK(m: mode_t) bool {
6645 return m & IFMT == IFSOCK;
6646 }
6647};
6648
6649const TFD_TIMER = packed struct(u32) {
6650 ABSTIME: bool = false,
6651 CANCEL_ON_SET: bool = false,
6652 _: u30 = 0,
6653};
6654
6655pub const TFD = switch (native_arch) {
6656 .sparc, .sparc64 => packed struct(u32) {
6657 _0: u14 = 0,
6658 NONBLOCK: bool = false,
6659 _15: u7 = 0,
6660 CLOEXEC: bool = false,
6661 _: u9 = 0,
6662
6663 pub const TIMER = TFD_TIMER;
6664 },
6665 .mips, .mipsel, .mips64, .mips64el => packed struct(u32) {
6666 _0: u7 = 0,
6667 NONBLOCK: bool = false,
6668 _8: u11 = 0,
6669 CLOEXEC: bool = false,
6670 _: u12 = 0,
6671
6672 pub const TIMER = TFD_TIMER;
6673 },
6674 .alpha => packed struct(u32) {
6675 _0: u2 = 0,
6676 NONBLOCK: bool = false,
6677 _3: u18 = 0,
6678 CLOEXEC: bool = false,
6679 _: u10 = 0,
6680
6681 pub const TIMER = TFD_TIMER;
6682 },
6683 else => packed struct(u32) {
6684 _0: u11 = 0,
6685 NONBLOCK: bool = false,
6686 _12: u7 = 0,
6687 CLOEXEC: bool = false,
6688 _: u12 = 0,
6689
6690 pub const TIMER = TFD_TIMER;
6691 },
6692};
6693
6694const k_sigaction_funcs = struct {
6695 const handler = ?*align(1) const fn (SIG) callconv(.c) void;
6696 const restorer = *const fn () callconv(.c) void;
6697};
6698
6699/// Kernel sigaction struct, as expected by the `rt_sigaction` syscall. Includes `restorer` on
6700/// targets where userspace is responsible for hooking up `rt_sigreturn`.
6701pub const k_sigaction = switch (native_arch) {
6702 .mips, .mipsel, .mips64, .mips64el => extern struct {
6703 flags: c_uint,
6704 handler: k_sigaction_funcs.handler,
6705 mask: sigset_t,
6706 },
6707 .csky, .hexagon, .loongarch32, .loongarch64, .or1k, .riscv32, .riscv64 => extern struct {
6708 handler: k_sigaction_funcs.handler,
6709 flags: c_ulong,
6710 mask: sigset_t,
6711 },
6712 .alpha => extern struct {
6713 handler: k_sigaction_funcs.handler,
6714 mask: sigset_t,
6715 flags: c_int,
6716 },
6717 .xtensa, .xtensaeb => extern struct {
6718 handler: k_sigaction_funcs.handler,
6719 mask: sigset_t,
6720 flags: c_ulong,
6721 restorer: k_sigaction_funcs.restorer,
6722 },
6723 else => extern struct {
6724 handler: k_sigaction_funcs.handler,
6725 flags: c_ulong,
6726 restorer: k_sigaction_funcs.restorer,
6727 mask: sigset_t,
6728 },
6729};
6730
6731/// Kernel Sigaction wrapper for the actual ABI `k_sigaction`. The Zig
6732/// linux.zig wrapper library still does some pre-processing on
6733/// sigaction() calls (to add the `restorer` field).
6734///
6735/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
6736pub const Sigaction = struct {
6737 pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
6738 pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
6739
6740 handler: extern union {
6741 handler: ?handler_fn,
6742 sigaction: ?sigaction_fn,
6743 },
6744 mask: sigset_t,
6745 flags: switch (native_arch) {
6746 .mips, .mipsel, .mips64, .mips64el => c_uint,
6747 .alpha => c_int,
6748 else => c_ulong,
6749 },
6750};
6751
6752pub const SFD = struct {
6753 pub const CLOEXEC = 1 << @bitOffsetOf(O, "CLOEXEC");
6754 pub const NONBLOCK = 1 << @bitOffsetOf(O, "NONBLOCK");
6755};
6756
6757pub const signalfd_siginfo = extern struct {
6758 signo: u32,
6759 errno: i32,
6760 code: i32,
6761 pid: u32,
6762 uid: uid_t,
6763 fd: i32,
6764 tid: u32,
6765 band: u32,
6766 overrun: u32,
6767 trapno: u32,
6768 status: i32,
6769 int: i32,
6770 ptr: u64,
6771 utime: u64,
6772 stime: u64,
6773 addr: u64,
6774 addr_lsb: u16,
6775 __pad2: u16,
6776 syscall: i32,
6777 call_addr: u64,
6778 native_arch: u32,
6779 __pad: [28]u8,
6780};
6781
6782pub const in_port_t = u16;
6783pub const sa_family_t = u16;
6784pub const socklen_t = u32;
6785
6786pub const sockaddr = extern struct {
6787 family: sa_family_t,
6788 data: [14]u8,
6789
6790 pub const SS_MAXSIZE = 128;
6791 pub const storage = extern struct {
6792 family: sa_family_t align(8),
6793 padding: [SS_MAXSIZE - @sizeOf(sa_family_t)]u8 = undefined,
6794
6795 comptime {
6796 assert(@sizeOf(storage) == SS_MAXSIZE);
6797 assert(@alignOf(storage) == 8);
6798 }
6799 };
6800
6801 /// IPv4 socket address
6802 pub const in = extern struct {
6803 family: sa_family_t = AF.INET,
6804 port: in_port_t,
6805 addr: u32,
6806 zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
6807 };
6808
6809 /// IPv6 socket address
6810 pub const in6 = extern struct {
6811 family: sa_family_t = AF.INET6,
6812 port: in_port_t,
6813 flowinfo: u32,
6814 addr: [16]u8,
6815 scope_id: u32,
6816 };
6817
6818 /// UNIX domain socket address
6819 pub const un = extern struct {
6820 family: sa_family_t = AF.UNIX,
6821 path: [108]u8,
6822 };
6823
6824 /// Packet socket address
6825 pub const ll = extern struct {
6826 family: sa_family_t = AF.PACKET,
6827 protocol: u16,
6828 ifindex: i32,
6829 hatype: u16,
6830 pkttype: u8,
6831 halen: u8,
6832 addr: [8]u8,
6833 };
6834
6835 /// Netlink socket address
6836 pub const nl = extern struct {
6837 family: sa_family_t = AF.NETLINK,
6838 __pad1: c_ushort = 0,
6839
6840 /// port ID
6841 pid: u32,
6842
6843 /// multicast groups mask
6844 groups: u32,
6845 };
6846
6847 pub const xdp = extern struct {
6848 family: u16 = AF.XDP,
6849 flags: u16,
6850 ifindex: u32,
6851 queue_id: u32,
6852 shared_umem_fd: u32,
6853 };
6854
6855 /// Address structure for vSockets
6856 pub const vm = extern struct {
6857 family: sa_family_t = AF.VSOCK,
6858 reserved1: u16 = 0,
6859 port: u32,
6860 cid: u32,
6861 flags: u8,
6862
6863 /// The total size of this structure should be exactly the same as that of struct sockaddr.
6864 zero: [3]u8 = @splat(0),
6865 comptime {
6866 std.debug.assert(@sizeOf(vm) == @sizeOf(sockaddr));
6867 }
6868 };
6869};
6870
6871pub const mmsghdr = extern struct {
6872 hdr: msghdr,
6873 len: u32,
6874};
6875
6876pub const epoll_data = extern union {
6877 ptr: usize,
6878 fd: i32,
6879 u32: u32,
6880 u64: u64,
6881};
6882
6883pub const epoll_event = extern struct {
6884 events: u32,
6885 data: epoll_data align(switch (native_arch) {
6886 .x86_64 => 4,
6887 else => @alignOf(epoll_data),
6888 }),
6889};
6890
6891pub const VFS_CAP_REVISION_MASK = 0xFF000000;
6892pub const VFS_CAP_REVISION_SHIFT = 24;
6893pub const VFS_CAP_FLAGS_MASK = ~@as(u32, VFS_CAP_REVISION_MASK);
6894pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;
6895
6896pub const VFS_CAP_REVISION_1 = 0x01000000;
6897pub const VFS_CAP_U32_1 = 1;
6898pub const XATTR_CAPS_SZ_1 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_1);
6899
6900pub const VFS_CAP_REVISION_2 = 0x02000000;
6901pub const VFS_CAP_U32_2 = 2;
6902pub const XATTR_CAPS_SZ_2 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_2);
6903
6904pub const XATTR_CAPS_SZ = XATTR_CAPS_SZ_2;
6905pub const VFS_CAP_U32 = VFS_CAP_U32_2;
6906pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;
6907
6908pub const vfs_cap_data = extern struct {
6909 //all of these are mandated as little endian
6910 //when on disk.
6911 const Data = extern struct {
6912 permitted: u32,
6913 inheritable: u32,
6914 };
6915
6916 magic_etc: u32,
6917 data: [VFS_CAP_U32]Data,
6918};
6919
6920pub const CAP = struct {
6921 pub const CHOWN = 0;
6922 pub const DAC_OVERRIDE = 1;
6923 pub const DAC_READ_SEARCH = 2;
6924 pub const FOWNER = 3;
6925 pub const FSETID = 4;
6926 pub const KILL = 5;
6927 pub const SETGID = 6;
6928 pub const SETUID = 7;
6929 pub const SETPCAP = 8;
6930 pub const LINUX_IMMUTABLE = 9;
6931 pub const NET_BIND_SERVICE = 10;
6932 pub const NET_BROADCAST = 11;
6933 pub const NET_ADMIN = 12;
6934 pub const NET_RAW = 13;
6935 pub const IPC_LOCK = 14;
6936 pub const IPC_OWNER = 15;
6937 pub const SYS_MODULE = 16;
6938 pub const SYS_RAWIO = 17;
6939 pub const SYS_CHROOT = 18;
6940 pub const SYS_PTRACE = 19;
6941 pub const SYS_PACCT = 20;
6942 pub const SYS_ADMIN = 21;
6943 pub const SYS_BOOT = 22;
6944 pub const SYS_NICE = 23;
6945 pub const SYS_RESOURCE = 24;
6946 pub const SYS_TIME = 25;
6947 pub const SYS_TTY_CONFIG = 26;
6948 pub const MKNOD = 27;
6949 pub const LEASE = 28;
6950 pub const AUDIT_WRITE = 29;
6951 pub const AUDIT_CONTROL = 30;
6952 pub const SETFCAP = 31;
6953 pub const MAC_OVERRIDE = 32;
6954 pub const MAC_ADMIN = 33;
6955 pub const SYSLOG = 34;
6956 pub const WAKE_ALARM = 35;
6957 pub const BLOCK_SUSPEND = 36;
6958 pub const AUDIT_READ = 37;
6959 pub const PERFMON = 38;
6960 pub const BPF = 39;
6961 pub const CHECKPOINT_RESTORE = 40;
6962 pub const LAST_CAP = CHECKPOINT_RESTORE;
6963
6964 pub fn valid(x: u8) bool {
6965 return x >= 0 and x <= LAST_CAP;
6966 }
6967
6968 pub fn TO_MASK(cap: u8) u32 {
6969 return @as(u32, 1) << @as(u5, @intCast(cap & 31));
6970 }
6971
6972 pub fn TO_INDEX(cap: u8) u8 {
6973 return cap >> 5;
6974 }
6975};
6976
6977pub const cap_t = extern struct {
6978 hdrp: *cap_user_header_t,
6979 datap: *cap_user_data_t,
6980};
6981
6982pub const cap_user_header_t = extern struct {
6983 version: u32,
6984 pid: usize,
6985};
6986
6987pub const cap_user_data_t = extern struct {
6988 effective: u32,
6989 permitted: u32,
6990 inheritable: u32,
6991};
6992
6993pub const inotify_event = extern struct {
6994 wd: i32,
6995 mask: u32,
6996 cookie: u32,
6997 len: u32,
6998 //name: [?]u8,
6999
7000 // if an event is returned for a directory or file inside the directory being watched
7001 // returns the name of said directory/file
7002 // returns `null` if the directory/file is the one being watched
7003 pub fn getName(self: *const inotify_event) ?[:0]const u8 {
7004 if (self.len == 0) return null;
7005 return std.mem.span(@as([*:0]const u8, @ptrCast(self)) + @sizeOf(inotify_event));
7006 }
7007};
7008
7009pub const dirent64 = extern struct {
7010 ino: u64,
7011 off: u64,
7012 reclen: u16,
7013 type: u8,
7014 name: [0]u8,
7015};
7016
7017pub const dl_phdr_info = extern struct {
7018 addr: usize,
7019 name: ?[*:0]const u8,
7020 phdr: [*]std.elf.ElfN.Phdr,
7021 phnum: u16,
7022};
7023
7024pub const CPU_SETSIZE = 128;
7025pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
7026pub const cpu_count_t = @Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));
7027
7028pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
7029 var sum: cpu_count_t = 0;
7030 for (set) |x| {
7031 sum += @popCount(x);
7032 }
7033 return sum;
7034}
7035
7036pub const MINSIGSTKSZ = switch (native_arch) {
7037 .arc,
7038 .arceb,
7039 .arm,
7040 .armeb,
7041 .csky,
7042 .hexagon,
7043 .m68k,
7044 .mips,
7045 .mipsel,
7046 .mips64,
7047 .mips64el,
7048 .microblaze,
7049 .microblazeel,
7050 .or1k,
7051 .powerpc,
7052 .powerpcle,
7053 .riscv32,
7054 .riscv64,
7055 .s390x,
7056 .sh,
7057 .sheb,
7058 .thumb,
7059 .thumbeb,
7060 .x86,
7061 .x86_64,
7062 .xtensa,
7063 .xtensaeb,
7064 => 2048,
7065 .loongarch32,
7066 .loongarch64,
7067 .sparc,
7068 .sparc64,
7069 => 4096,
7070 .aarch64,
7071 .aarch64_be,
7072 => 5120,
7073 .powerpc64,
7074 .powerpc64le,
7075 => 8192,
7076 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
7077};
7078pub const SIGSTKSZ = switch (native_arch) {
7079 .arc,
7080 .arceb,
7081 .arm,
7082 .armeb,
7083 .csky,
7084 .hexagon,
7085 .m68k,
7086 .mips,
7087 .mipsel,
7088 .mips64,
7089 .mips64el,
7090 .microblaze,
7091 .microblazeel,
7092 .or1k,
7093 .powerpc,
7094 .powerpcle,
7095 .riscv32,
7096 .riscv64,
7097 .s390x,
7098 .sh,
7099 .sheb,
7100 .thumb,
7101 .thumbeb,
7102 .x86,
7103 .x86_64,
7104 .xtensa,
7105 .xtensaeb,
7106 => 8192,
7107 .aarch64,
7108 .aarch64_be,
7109 .loongarch32,
7110 .loongarch64,
7111 .sparc,
7112 .sparc64,
7113 => 16384,
7114 .powerpc64,
7115 .powerpc64le,
7116 => 32768,
7117 else => @compileError("SIGSTKSZ not defined for this architecture"),
7118};
7119
7120pub const SS = struct {
7121 pub const ONSTACK = 1;
7122 pub const DISABLE = 2;
7123 pub const AUTODISARM = 1 << 31;
7124};
7125
7126pub const stack_t = if (is_mips)
7127 // IRIX compatible stack_t
7128 extern struct {
7129 sp: [*]u8,
7130 size: usize,
7131 flags: i32,
7132 }
7133else
7134 extern struct {
7135 sp: [*]u8,
7136 flags: i32,
7137 size: usize,
7138 };
7139
7140pub const sigval = extern union {
7141 int: i32,
7142 ptr: *anyopaque,
7143};
7144
7145const siginfo_fields_union = extern union {
7146 pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8,
7147 common: extern struct {
7148 first: extern union {
7149 piduid: extern struct {
7150 pid: pid_t,
7151 uid: uid_t,
7152 },
7153 timer: extern struct {
7154 timerid: i32,
7155 overrun: i32,
7156 },
7157 },
7158 second: extern union {
7159 value: sigval,
7160 sigchld: extern struct {
7161 status: i32,
7162 utime: clock_t,
7163 stime: clock_t,
7164 },
7165 },
7166 },
7167 sigfault: extern struct {
7168 addr: *allowzero anyopaque,
7169 addr_lsb: i16,
7170 first: extern union {
7171 addr_bnd: extern struct {
7172 lower: *anyopaque,
7173 upper: *anyopaque,
7174 },
7175 pkey: u32,
7176 },
7177 },
7178 sigpoll: extern struct {
7179 band: isize,
7180 fd: i32,
7181 },
7182 sigsys: extern struct {
7183 call_addr: *anyopaque,
7184 syscall: i32,
7185 native_arch: u32,
7186 },
7187};
7188
7189pub const CLD = enum(i32) {
7190 EXITED = 1,
7191 KILLED = 2,
7192 DUMPED = 3,
7193 TRAPPED = 4,
7194 STOPPED = 5,
7195 CONTINUED = 6,
7196 _,
7197};
7198
7199pub const siginfo_t = if (is_mips)
7200 extern struct {
7201 signo: SIG,
7202 code: i32,
7203 errno: i32,
7204 fields: siginfo_fields_union,
7205 }
7206else
7207 extern struct {
7208 signo: SIG,
7209 errno: i32,
7210 code: i32,
7211 fields: siginfo_fields_union,
7212 };
7213
7214// io_uring_params.flags
7215
7216/// io_context is polled
7217pub const IORING_SETUP_IOPOLL = 1 << 0;
7218
7219/// SQ poll thread
7220pub const IORING_SETUP_SQPOLL = 1 << 1;
7221
7222/// sq_thread_cpu is valid
7223pub const IORING_SETUP_SQ_AFF = 1 << 2;
7224
7225/// app defines CQ size
7226pub const IORING_SETUP_CQSIZE = 1 << 3;
7227
7228/// clamp SQ/CQ ring sizes
7229pub const IORING_SETUP_CLAMP = 1 << 4;
7230
7231/// attach to existing wq
7232pub const IORING_SETUP_ATTACH_WQ = 1 << 5;
7233
7234/// start with ring disabled
7235pub const IORING_SETUP_R_DISABLED = 1 << 6;
7236
7237/// continue submit on error
7238pub const IORING_SETUP_SUBMIT_ALL = 1 << 7;
7239
7240/// Cooperative task running. When requests complete, they often require
7241/// forcing the submitter to transition to the kernel to complete. If this
7242/// flag is set, work will be done when the task transitions anyway, rather
7243/// than force an inter-processor interrupt reschedule. This avoids interrupting
7244/// a task running in userspace, and saves an IPI.
7245pub const IORING_SETUP_COOP_TASKRUN = 1 << 8;
7246
7247/// If COOP_TASKRUN is set, get notified if task work is available for
7248/// running and a kernel transition would be needed to run it. This sets
7249/// IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN.
7250pub const IORING_SETUP_TASKRUN_FLAG = 1 << 9;
7251
7252/// SQEs are 128 byte
7253pub const IORING_SETUP_SQE128 = 1 << 10;
7254/// CQEs are 32 byte
7255pub const IORING_SETUP_CQE32 = 1 << 11;
7256
7257/// Only one task is allowed to submit requests
7258pub const IORING_SETUP_SINGLE_ISSUER = 1 << 12;
7259
7260/// Defer running task work to get events.
7261/// Rather than running bits of task work whenever the task transitions
7262/// try to do it just before it is needed.
7263pub const IORING_SETUP_DEFER_TASKRUN = 1 << 13;
7264
7265/// Application provides ring memory
7266pub const IORING_SETUP_NO_MMAP = 1 << 14;
7267
7268/// Register the ring fd in itself for use with
7269/// IORING_REGISTER_USE_REGISTERED_RING; return a registered fd index rather
7270/// than an fd.
7271pub const IORING_SETUP_REGISTERED_FD_ONLY = 1 << 15;
7272
7273/// Removes indirection through the SQ index array.
7274pub const IORING_SETUP_NO_SQARRAY = 1 << 16;
7275
7276/// IO submission data structure (Submission Queue Entry)
7277pub const io_uring_sqe = @import("linux/io_uring_sqe.zig").io_uring_sqe;
7278
7279pub const IoUring = @import("linux/IoUring.zig");
7280
7281/// If sqe->file_index is set to this for opcodes that instantiate a new
7282/// direct descriptor (like openat/openat2/accept), then io_uring will allocate
7283/// an available direct descriptor instead of having the application pass one
7284/// in. The picked direct descriptor will be returned in cqe->res, or -ENFILE
7285/// if the space is full.
7286/// Available since Linux 5.19
7287pub const IORING_FILE_INDEX_ALLOC = maxInt(u32);
7288
7289pub const IOSQE_BIT = enum(u8) {
7290 FIXED_FILE,
7291 IO_DRAIN,
7292 IO_LINK,
7293 IO_HARDLINK,
7294 ASYNC,
7295 BUFFER_SELECT,
7296 CQE_SKIP_SUCCESS,
7297
7298 _,
7299};
7300
7301// io_uring_sqe.flags
7302
7303/// use fixed fileset
7304pub const IOSQE_FIXED_FILE = 1 << @backingInt(IOSQE_BIT.FIXED_FILE);
7305
7306/// issue after inflight IO
7307pub const IOSQE_IO_DRAIN = 1 << @backingInt(IOSQE_BIT.IO_DRAIN);
7308
7309/// links next sqe
7310pub const IOSQE_IO_LINK = 1 << @backingInt(IOSQE_BIT.IO_LINK);
7311
7312/// like LINK, but stronger
7313pub const IOSQE_IO_HARDLINK = 1 << @backingInt(IOSQE_BIT.IO_HARDLINK);
7314
7315/// always go async
7316pub const IOSQE_ASYNC = 1 << @backingInt(IOSQE_BIT.ASYNC);
7317
7318/// select buffer from buf_group
7319pub const IOSQE_BUFFER_SELECT = 1 << @backingInt(IOSQE_BIT.BUFFER_SELECT);
7320
7321/// don't post CQE if request succeeded
7322/// Available since Linux 5.17
7323pub const IOSQE_CQE_SKIP_SUCCESS = 1 << @backingInt(IOSQE_BIT.CQE_SKIP_SUCCESS);
7324
7325pub const IORING_OP = enum(u8) {
7326 NOP,
7327 READV,
7328 WRITEV,
7329 FSYNC,
7330 READ_FIXED,
7331 WRITE_FIXED,
7332 POLL_ADD,
7333 POLL_REMOVE,
7334 SYNC_FILE_RANGE,
7335 SENDMSG,
7336 RECVMSG,
7337 TIMEOUT,
7338 TIMEOUT_REMOVE,
7339 ACCEPT,
7340 ASYNC_CANCEL,
7341 LINK_TIMEOUT,
7342 CONNECT,
7343 FALLOCATE,
7344 OPENAT,
7345 CLOSE,
7346 FILES_UPDATE,
7347 STATX,
7348 READ,
7349 WRITE,
7350 FADVISE,
7351 MADVISE,
7352 SEND,
7353 RECV,
7354 OPENAT2,
7355 EPOLL_CTL,
7356 SPLICE,
7357 PROVIDE_BUFFERS,
7358 REMOVE_BUFFERS,
7359 TEE,
7360 SHUTDOWN,
7361 RENAMEAT,
7362 UNLINKAT,
7363 MKDIRAT,
7364 SYMLINKAT,
7365 LINKAT,
7366 MSG_RING,
7367 FSETXATTR,
7368 SETXATTR,
7369 FGETXATTR,
7370 GETXATTR,
7371 SOCKET,
7372 URING_CMD,
7373 SEND_ZC,
7374 SENDMSG_ZC,
7375 READ_MULTISHOT,
7376 WAITID,
7377 FUTEX_WAIT,
7378 FUTEX_WAKE,
7379 FUTEX_WAITV,
7380 FIXED_FD_INSTALL,
7381 FTRUNCATE,
7382 BIND,
7383 LISTEN,
7384 RECV_ZC,
7385
7386 _,
7387};
7388// io_uring_sqe.uring_cmd_flags (rw_flags in the Zig struct)
7389
7390/// use registered buffer; pass thig flag along with setting sqe->buf_index.
7391pub const IORING_URING_CMD_FIXED = 1 << 0;
7392
7393// io_uring_sqe.fsync_flags (rw_flags in the Zig struct)
7394pub const IORING_FSYNC_DATASYNC = 1 << 0;
7395
7396// io_uring_sqe.timeout_flags (rw_flags in the Zig struct)
7397pub const IORING_TIMEOUT_ABS = 1 << 0;
7398pub const IORING_TIMEOUT_UPDATE = 1 << 1; // Available since Linux 5.11
7399pub const IORING_TIMEOUT_BOOTTIME = 1 << 2; // Available since Linux 5.15
7400pub const IORING_TIMEOUT_REALTIME = 1 << 3; // Available since Linux 5.15
7401pub const IORING_LINK_TIMEOUT_UPDATE = 1 << 4; // Available since Linux 5.15
7402pub const IORING_TIMEOUT_ETIME_SUCCESS = 1 << 5; // Available since Linux 5.16
7403pub const IORING_TIMEOUT_CLOCK_MASK = IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME;
7404pub const IORING_TIMEOUT_UPDATE_MASK = IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE;
7405
7406// io_uring_sqe.splice_flags (rw_flags in the Zig struct)
7407// extends splice(2) flags
7408pub const IORING_SPLICE_F_FD_IN_FIXED = 1 << 31;
7409
7410// POLL_ADD flags.
7411// Note that since sqe->poll_events (rw_flags in the Zig struct) is the flag space, the command flags for POLL_ADD are stored in sqe->len.
7412
7413/// Multishot poll. Sets IORING_CQE_F_MORE if the poll handler will continue to report CQEs on behalf of the same SQE.
7414pub const IORING_POLL_ADD_MULTI = 1 << 0;
7415/// Update existing poll request, matching sqe->addr as the old user_data field.
7416pub const IORING_POLL_UPDATE_EVENTS = 1 << 1;
7417pub const IORING_POLL_UPDATE_USER_DATA = 1 << 2;
7418pub const IORING_POLL_ADD_LEVEL = 1 << 3;
7419
7420// ASYNC_CANCEL flags.
7421
7422/// Cancel all requests that match the given key
7423pub const IORING_ASYNC_CANCEL_ALL = 1 << 0;
7424/// Key off 'fd' for cancelation rather than the request 'user_data'.
7425pub const IORING_ASYNC_CANCEL_FD = 1 << 1;
7426/// Match any request
7427pub const IORING_ASYNC_CANCEL_ANY = 1 << 2;
7428/// 'fd' passed in is a fixed descriptor. Available since Linux 6.0
7429pub const IORING_ASYNC_CANCEL_FD_FIXED = 1 << 3;
7430
7431// send/sendmsg and recv/recvmsg flags (sqe->ioprio)
7432
7433/// If set, instead of first attempting to send or receive and arm poll if that yields an -EAGAIN result,
7434/// arm poll upfront and skip the initial transfer attempt.
7435pub const IORING_RECVSEND_POLL_FIRST = 1 << 0;
7436/// Multishot recv. Sets IORING_CQE_F_MORE if the handler will continue to report CQEs on behalf of the same SQE.
7437pub const IORING_RECV_MULTISHOT = 1 << 1;
7438/// Use registered buffers, the index is stored in the buf_index field.
7439pub const IORING_RECVSEND_FIXED_BUF = 1 << 2;
7440/// If set, SEND[MSG]_ZC should report the zerocopy usage in cqe.res for the IORING_CQE_F_NOTIF cqe.
7441pub const IORING_SEND_ZC_REPORT_USAGE = 1 << 3;
7442/// If set, send or recv will grab as many buffers from the buffer group ID given and send them all.
7443/// The completion result will be the number of buffers send, with the starting buffer ID in cqe as per usual.
7444/// The buffers be contigious from the starting buffer ID.
7445/// Used with IOSQE_BUFFER_SELECT.
7446pub const IORING_RECVSEND_BUNDLE = 1 << 4;
7447/// CQE.RES FOR IORING_CQE_F_NOTIF if IORING_SEND_ZC_REPORT_USAGE was requested
7448pub const IORING_NOTIF_USAGE_ZC_COPIED = 1 << 31;
7449
7450/// accept flags stored in sqe->iopri
7451pub const IORING_ACCEPT_MULTISHOT = 1 << 0;
7452
7453/// IORING_OP_MSG_RING command types, stored in sqe->addr
7454pub const IORING_MSG_RING_COMMAND = enum(u8) {
7455 /// pass sqe->len as 'res' and off as user_data
7456 DATA = 0,
7457 /// send a registered fd to another ring
7458 SEND_FD = 1,
7459 _,
7460};
7461
7462// io_uring_sqe.msg_ring_flags (rw_flags in the Zig struct)
7463
7464/// Don't post a CQE to the target ring. Not applicable for IORING_MSG_DATA, obviously.
7465pub const IORING_MSG_RING_CQE_SKIP = 1 << 0;
7466
7467/// Pass through the flags from sqe->file_index (splice_fd_in in the zig struct) to cqe->flags */
7468pub const IORING_MSG_RING_FLAGS_PASS = 1 << 1;
7469
7470// IO completion data structure (Completion Queue Entry)
7471pub const io_uring_cqe = extern struct {
7472 /// io_uring_sqe.data submission passed back
7473 user_data: u64,
7474
7475 /// result code for this event
7476 res: i32,
7477 flags: u32,
7478
7479 // Followed by 16 bytes of padding if initialized with IORING_SETUP_CQE32, doubling cqe size
7480
7481 pub fn err(self: io_uring_cqe) E {
7482 if (self.res > -4096 and self.res < 0) {
7483 return @as(E, @fromBackingInt(@intCast(-self.res)));
7484 }
7485 return .SUCCESS;
7486 }
7487
7488 // On successful completion of the provided buffers IO request, the CQE flags field
7489 // will have IORING_CQE_F_BUFFER set and the selected buffer ID will be indicated by
7490 // the upper 16-bits of the flags field.
7491 pub fn buffer_id(self: io_uring_cqe) !u16 {
7492 if (self.flags & IORING_CQE_F_BUFFER != IORING_CQE_F_BUFFER) {
7493 return error.NoBufferSelected;
7494 }
7495 return @as(u16, @intCast(self.flags >> IORING_CQE_BUFFER_SHIFT));
7496 }
7497};
7498
7499// io_uring_cqe.flags
7500
7501/// If set, the upper 16 bits are the buffer ID
7502pub const IORING_CQE_F_BUFFER = 1 << 0;
7503/// If set, parent SQE will generate more CQE entries.
7504/// Available since Linux 5.13.
7505pub const IORING_CQE_F_MORE = 1 << 1;
7506/// If set, more data to read after socket recv
7507pub const IORING_CQE_F_SOCK_NONEMPTY = 1 << 2;
7508/// Set for notification CQEs. Can be used to distinct them from sends.
7509pub const IORING_CQE_F_NOTIF = 1 << 3;
7510/// If set, the buffer ID set in the completion will get more completions.
7511pub const IORING_CQE_F_BUF_MORE = 1 << 4;
7512pub const IORING_CQE_F_SKIP = 1 << 5;
7513pub const IORING_CQE_F_32 = 1 << 15;
7514
7515pub const IORING_CQE_BUFFER_SHIFT = 16;
7516
7517/// Magic offsets for the application to mmap the data it needs
7518pub const IORING_OFF_SQ_RING = 0;
7519pub const IORING_OFF_CQ_RING = 0x8000000;
7520pub const IORING_OFF_SQES = 0x10000000;
7521
7522/// Filled with the offset for mmap(2)
7523pub const io_sqring_offsets = extern struct {
7524 /// offset of ring head
7525 head: u32,
7526
7527 /// offset of ring tail
7528 tail: u32,
7529
7530 /// ring mask value
7531 ring_mask: u32,
7532
7533 /// entries in ring
7534 ring_entries: u32,
7535
7536 /// ring flags
7537 flags: u32,
7538
7539 /// number of sqes not submitted
7540 dropped: u32,
7541
7542 /// sqe index array
7543 array: u32,
7544
7545 resv1: u32,
7546 user_addr: u64,
7547};
7548
7549// io_sqring_offsets.flags
7550
7551/// needs io_uring_enter wakeup
7552pub const IORING_SQ_NEED_WAKEUP = 1 << 0;
7553/// kernel has cqes waiting beyond the cq ring
7554pub const IORING_SQ_CQ_OVERFLOW = 1 << 1;
7555/// task should enter the kernel
7556pub const IORING_SQ_TASKRUN = 1 << 2;
7557
7558pub const io_cqring_offsets = extern struct {
7559 head: u32,
7560 tail: u32,
7561 ring_mask: u32,
7562 ring_entries: u32,
7563 overflow: u32,
7564 cqes: u32,
7565 flags: u32,
7566 resv: u32,
7567 user_addr: u64,
7568};
7569
7570// io_cqring_offsets.flags
7571
7572/// disable eventfd notifications
7573pub const IORING_CQ_EVENTFD_DISABLED = 1 << 0;
7574
7575// io_uring_enter flags
7576pub const IORING_ENTER_GETEVENTS = 1 << 0;
7577pub const IORING_ENTER_SQ_WAKEUP = 1 << 1;
7578pub const IORING_ENTER_SQ_WAIT = 1 << 2;
7579pub const IORING_ENTER_EXT_ARG = 1 << 3;
7580pub const IORING_ENTER_REGISTERED_RING = 1 << 4;
7581
7582pub const io_uring_params = extern struct {
7583 sq_entries: u32,
7584 cq_entries: u32,
7585 flags: u32,
7586 sq_thread_cpu: u32,
7587 sq_thread_idle: u32,
7588 features: u32,
7589 wq_fd: u32,
7590 resv: [3]u32,
7591 sq_off: io_sqring_offsets,
7592 cq_off: io_cqring_offsets,
7593};
7594
7595// io_uring_params.features flags
7596
7597pub const IORING_FEAT_SINGLE_MMAP = 1 << 0;
7598pub const IORING_FEAT_NODROP = 1 << 1;
7599pub const IORING_FEAT_SUBMIT_STABLE = 1 << 2;
7600pub const IORING_FEAT_RW_CUR_POS = 1 << 3;
7601pub const IORING_FEAT_CUR_PERSONALITY = 1 << 4;
7602pub const IORING_FEAT_FAST_POLL = 1 << 5;
7603pub const IORING_FEAT_POLL_32BITS = 1 << 6;
7604pub const IORING_FEAT_SQPOLL_NONFIXED = 1 << 7;
7605pub const IORING_FEAT_EXT_ARG = 1 << 8;
7606pub const IORING_FEAT_NATIVE_WORKERS = 1 << 9;
7607pub const IORING_FEAT_RSRC_TAGS = 1 << 10;
7608pub const IORING_FEAT_CQE_SKIP = 1 << 11;
7609pub const IORING_FEAT_LINKED_FILE = 1 << 12;
7610
7611// io_uring_register opcodes and arguments
7612pub const IORING_REGISTER = enum(u32) {
7613 REGISTER_BUFFERS,
7614 UNREGISTER_BUFFERS,
7615 REGISTER_FILES,
7616 UNREGISTER_FILES,
7617 REGISTER_EVENTFD,
7618 UNREGISTER_EVENTFD,
7619 REGISTER_FILES_UPDATE,
7620 REGISTER_EVENTFD_ASYNC,
7621 REGISTER_PROBE,
7622 REGISTER_PERSONALITY,
7623 UNREGISTER_PERSONALITY,
7624 REGISTER_RESTRICTIONS,
7625 REGISTER_ENABLE_RINGS,
7626
7627 // extended with tagging
7628 REGISTER_FILES2,
7629 REGISTER_FILES_UPDATE2,
7630 REGISTER_BUFFERS2,
7631 REGISTER_BUFFERS_UPDATE,
7632
7633 // set/clear io-wq thread affinities
7634 REGISTER_IOWQ_AFF,
7635 UNREGISTER_IOWQ_AFF,
7636
7637 // set/get max number of io-wq workers
7638 REGISTER_IOWQ_MAX_WORKERS,
7639
7640 // register/unregister io_uring fd with the ring
7641 REGISTER_RING_FDS,
7642 UNREGISTER_RING_FDS,
7643
7644 // register ring based provide buffer group
7645 REGISTER_PBUF_RING,
7646 UNREGISTER_PBUF_RING,
7647
7648 // sync cancelation API
7649 REGISTER_SYNC_CANCEL,
7650
7651 // register a range of fixed file slots for automatic slot allocation
7652 REGISTER_FILE_ALLOC_RANGE,
7653
7654 // return status information for a buffer group
7655 REGISTER_PBUF_STATUS,
7656
7657 // set/clear busy poll settings
7658 REGISTER_NAPI,
7659 UNREGISTER_NAPI,
7660
7661 REGISTER_CLOCK,
7662
7663 // clone registered buffers from source ring to current ring
7664 REGISTER_CLONE_BUFFERS,
7665
7666 // send MSG_RING without having a ring
7667 REGISTER_SEND_MSG_RING,
7668
7669 // register a netdev hw rx queue for zerocopy
7670 REGISTER_ZCRX_IFQ,
7671
7672 // resize CQ ring
7673 REGISTER_RESIZE_RINGS,
7674
7675 REGISTER_MEM_REGION,
7676
7677 // flag added to the opcode to use a registered ring fd
7678 REGISTER_USE_REGISTERED_RING = 1 << 31,
7679
7680 _,
7681};
7682
7683/// io_uring_restriction->opcode values
7684pub const IOWQ_CATEGORIES = enum(u8) {
7685 BOUND,
7686 UNBOUND,
7687};
7688
7689/// deprecated, see struct io_uring_rsrc_update
7690pub const io_uring_files_update = extern struct {
7691 offset: u32,
7692 resv: u32,
7693 fds: u64,
7694};
7695
7696/// Register a fully sparse file space, rather than pass in an array of all -1 file descriptors.
7697pub const IORING_RSRC_REGISTER_SPARSE = 1 << 0;
7698
7699pub const io_uring_rsrc_register = extern struct {
7700 nr: u32,
7701 flags: u32,
7702 resv2: u64,
7703 data: u64,
7704 tags: u64,
7705};
7706
7707pub const io_uring_rsrc_update = extern struct {
7708 offset: u32,
7709 resv: u32,
7710 data: u64,
7711};
7712
7713pub const io_uring_rsrc_update2 = extern struct {
7714 offset: u32,
7715 resv: u32,
7716 data: u64,
7717 tags: u64,
7718 nr: u32,
7719 resv2: u32,
7720};
7721
7722pub const io_uring_notification_slot = extern struct {
7723 tag: u64,
7724 resv: [3]u64,
7725};
7726
7727pub const io_uring_notification_register = extern struct {
7728 nr_slots: u32,
7729 resv: u32,
7730 resv2: u64,
7731 data: u64,
7732 resv3: u64,
7733};
7734
7735pub const io_uring_napi = extern struct {
7736 busy_poll_to: u32,
7737 prefer_busy_poll: u8,
7738 _pad: [3]u8,
7739 resv: u64,
7740};
7741
7742/// Skip updating fd indexes set to this value in the fd table */
7743pub const IORING_REGISTER_FILES_SKIP = -2;
7744
7745pub const IO_URING_OP_SUPPORTED = 1 << 0;
7746
7747pub const io_uring_probe_op = extern struct {
7748 op: IORING_OP,
7749 resv: u8,
7750 /// IO_URING_OP_* flags
7751 flags: u16,
7752 resv2: u32,
7753
7754 pub fn is_supported(self: @This()) bool {
7755 return self.flags & IO_URING_OP_SUPPORTED != 0;
7756 }
7757};
7758
7759pub const io_uring_probe = extern struct {
7760 /// Last opcode supported
7761 last_op: IORING_OP,
7762 /// Length of ops[] array below
7763 ops_len: u8,
7764 resv: u16,
7765 resv2: [3]u32,
7766 ops: [256]io_uring_probe_op,
7767
7768 /// Is the operation supported on the running kernel.
7769 pub fn is_supported(self: @This(), op: IORING_OP) bool {
7770 const i = @backingInt(op);
7771 if (i > @backingInt(self.last_op) or i >= self.ops_len)
7772 return false;
7773 return self.ops[i].is_supported();
7774 }
7775};
7776
7777pub const io_uring_restriction = extern struct {
7778 opcode: IORING_RESTRICTION,
7779 arg: extern union {
7780 /// IORING_RESTRICTION_REGISTER_OP
7781 register_op: IORING_REGISTER,
7782
7783 /// IORING_RESTRICTION_SQE_OP
7784 sqe_op: IORING_OP,
7785
7786 /// IORING_RESTRICTION_SQE_FLAGS_*
7787 sqe_flags: u8,
7788 },
7789 resv: u8,
7790 resv2: [3]u32,
7791};
7792
7793/// io_uring_restriction->opcode values
7794pub const IORING_RESTRICTION = enum(u16) {
7795 /// Allow an io_uring_register(2) opcode
7796 REGISTER_OP = 0,
7797
7798 /// Allow an sqe opcode
7799 SQE_OP = 1,
7800
7801 /// Allow sqe flags
7802 SQE_FLAGS_ALLOWED = 2,
7803
7804 /// Require sqe flags (these flags must be set on each submission)
7805 SQE_FLAGS_REQUIRED = 3,
7806
7807 _,
7808};
7809
7810pub const IO_URING_SOCKET_OP = enum(u32) {
7811 SIOCIN = 0,
7812 SIOCOUTQ = 1,
7813 GETSOCKOPT = 2,
7814 SETSOCKOPT = 3,
7815};
7816
7817pub const io_uring_buf = extern struct {
7818 addr: u64,
7819 len: u32,
7820 bid: u16,
7821 resv: u16,
7822};
7823
7824pub const io_uring_buf_ring = extern struct {
7825 resv1: u64,
7826 resv2: u32,
7827 resv3: u16,
7828 tail: u16,
7829};
7830
7831/// argument for IORING_(UN)REGISTER_PBUF_RING
7832pub const io_uring_buf_reg = extern struct {
7833 ring_addr: u64,
7834 ring_entries: u32,
7835 bgid: u16,
7836 flags: Flags,
7837 resv: [3]u64,
7838
7839 pub const Flags = packed struct(u16) {
7840 _0: u1 = 0,
7841 /// Incremental buffer consumption.
7842 inc: bool,
7843 _: u14 = 0,
7844 };
7845};
7846
7847pub const io_uring_getevents_arg = extern struct {
7848 sigmask: u64,
7849 sigmask_sz: u32,
7850 pad: u32,
7851 ts: u64,
7852};
7853
7854/// Argument for IORING_REGISTER_SYNC_CANCEL
7855pub const io_uring_sync_cancel_reg = extern struct {
7856 addr: u64,
7857 fd: i32,
7858 flags: u32,
7859 timeout: kernel_timespec,
7860 pad: [4]u64,
7861};
7862
7863/// Argument for IORING_REGISTER_FILE_ALLOC_RANGE
7864/// The range is specified as [off, off + len)
7865pub const io_uring_file_index_range = extern struct {
7866 off: u32,
7867 len: u32,
7868 resv: u64,
7869};
7870
7871pub const io_uring_recvmsg_out = extern struct {
7872 namelen: u32,
7873 controllen: u32,
7874 payloadlen: u32,
7875 flags: u32,
7876};
7877
7878pub const utsname = extern struct {
7879 sysname: [64:0]u8,
7880 nodename: [64:0]u8,
7881 release: [64:0]u8,
7882 version: [64:0]u8,
7883 machine: [64:0]u8,
7884 domainname: [64:0]u8,
7885};
7886pub const HOST_NAME_MAX = 64;
7887
7888pub const STATX = packed struct(u32) {
7889 /// Want `mode & S.IFMT`.
7890 TYPE: bool = false,
7891 /// Want `mode & ~S.IFMT`.
7892 MODE: bool = false,
7893 /// Want the `nlink` member.
7894 NLINK: bool = false,
7895 /// Want the `uid` member.
7896 UID: bool = false,
7897 /// Want the `gid` member.
7898 GID: bool = false,
7899 /// Want the `atime` member.
7900 ATIME: bool = false,
7901 /// Want the `mtime` member.
7902 MTIME: bool = false,
7903 /// Want the `ctime` member.
7904 CTIME: bool = false,
7905 /// Want the `ino` member.
7906 INO: bool = false,
7907 /// Want the `size` member.
7908 SIZE: bool = false,
7909 /// Want the `blocks` member.
7910 BLOCKS: bool = false,
7911 /// Want the `btime` member.
7912 BTIME: bool = false,
7913 /// Want the `mnt_id` member.
7914 MNT_ID: bool = false,
7915 /// Want the `dio_mem_align` and `dio_offset_align` members.
7916 DIOALIGN: bool = false,
7917 /// Want the `stx_mnt_id` member.
7918 MNT_ID_UNIQUE: bool = false,
7919 /// Want the `sub` member.
7920 SUBVOL: bool = false,
7921 /// Want the `atomic_write_unit_min`, `atomic_write_unit_max` and
7922 /// `atomic_write_segments_max` members.
7923 WRITE_ATOMIC: bool = false,
7924 /// Want the `dio_read_offset_align` member.
7925 DIO_READ_ALIGN: bool = false,
7926 __pad: u13 = 0,
7927 /// Reserved for future expansion; must not be set.
7928 __RESERVED: bool = false,
7929
7930 pub const BASIC_STATS: STATX = @bitCast(@as(u32, 0x7ff));
7931};
7932
7933/// Attributes about the state or features of a file as a bitmask.
7934/// Flags marked [I] correspond to the `FS_IOC_SETFLAGS` values semantically.
7935/// See [FS_IOC_SETFLAGS(2const)](https://man7.org/linux/man-pages/man2/FS_IOC_GETFLAGS.2const.html)
7936/// for more.
7937pub const STATX_ATTR = packed struct(u64) {
7938 __pad1: u3 = 0,
7939 /// [I] File is compressed by the fs.
7940 COMPRESSED: bool = false,
7941 __pad2: u1 = 0,
7942 /// [I] File is marked immutable.
7943 IMMUTABLE: bool = false,
7944 /// [I] File is append-only.
7945 APPEND: bool = false,
7946 /// [I] File is not to be dumped.
7947 NODUMP: bool = false,
7948 /// [I] File requires a key to decrypt in the filesystem.
7949 ENCRYPTED: bool = false,
7950 /// File names a directory that triggers an automount.
7951 AUTOMOUNT: bool = false,
7952 /// File names the root of a mount.
7953 MOUNT_ROOT: bool = false,
7954 /// [I] File is protected by the `dm-verity` device.
7955 VERITY: bool = false,
7956 /// File is currently in the CPU direct access state.
7957 /// Does not correspond to the per-inode DAX flag that some filesystems support.
7958 DAX: bool = false,
7959 /// File supports atomic write operations.
7960 WRITE_ATOMIC: bool = false,
7961 __pad3: u50 = 0,
7962};
7963
7964pub const statx_timestamp = extern struct {
7965 /// Number of seconds before or after `1970-01-01T00:00:00Z`.
7966 sec: i64,
7967 /// Number of nanoseconds (0..999,999,999) after `sec`.
7968 nsec: u32,
7969 // Reserved for future increases in resolution.
7970 __pad1: u32,
7971};
7972
7973/// Renamed to `Statx` to not conflict with the `statx` function.
7974pub const Statx = extern struct {
7975 /// Mask of bits indicating filled fields. Updated with what information
7976 /// the kernel returned. Callers must check this field since support varies
7977 /// by kernel version and filesystem.
7978 mask: STATX,
7979 /// Block size for filesystem I/O.
7980 blksize: u32,
7981 /// Extra file attribute indicators.
7982 attributes: STATX_ATTR,
7983 /// Number of hard links.
7984 nlink: u32,
7985 /// User ID of owner.
7986 uid: uid_t,
7987 /// Group ID of owner.
7988 gid: gid_t,
7989 /// File type and mode.
7990 mode: u16,
7991 __spare0: u16,
7992 /// Inode number.
7993 ino: u64,
7994 /// Total size in bytes.
7995 size: u64,
7996 /// Number of 512B blocks allocated.
7997 blocks: u64,
7998 /// Mask to show what's supported in `attributes`.
7999 attributes_mask: STATX_ATTR,
8000 /// Last access file timestamp.
8001 atime: statx_timestamp,
8002 /// Creation file timestamp.
8003 btime: statx_timestamp,
8004 /// Last status change file timestamp.
8005 ctime: statx_timestamp,
8006 /// Last modification file timestamp.
8007 mtime: statx_timestamp,
8008 /// Major ID, if this file represents a device.
8009 rdev_major: u32,
8010 /// Minor ID, if this file represents a device.
8011 rdev_minor: u32,
8012 /// Major ID of the device containing the filesystem where this file resides.
8013 dev_major: u32,
8014 /// Minor ID of the device containing the filesystem where this file resides.
8015 dev_minor: u32,
8016 /// Mount ID
8017 mnt_id: u64,
8018 /// Memory buffer alignment for direct I/O.
8019 dio_mem_align: u32,
8020 /// File offset alignment for direct I/O.
8021 dio_offset_align: u32,
8022 /// Subvolume identifier.
8023 subvol: u64,
8024 /// Min atomic write unit in bytes.
8025 atomic_write_unit_min: u32,
8026 /// Max atomic write unit in bytes.
8027 atomic_write_unit_max: u32,
8028 /// Max atomic write segment count.
8029 atomic_write_segments_max: u32,
8030 /// File offset alignment for direct I/O reads.
8031 dio_read_offset_align: u32,
8032 /// Optimised max atomic write unit in bytes.
8033 atomic_write_unit_max_opt: u32,
8034 __spare2: [1]u32,
8035 __spare3: [8]u64,
8036};
8037
8038comptime {
8039 assert(@sizeOf(Statx) == 0x100);
8040}
8041
8042pub const addrinfo = extern struct {
8043 flags: AI,
8044 family: i32,
8045 socktype: i32,
8046 protocol: i32,
8047 addrlen: socklen_t,
8048 addr: ?*sockaddr,
8049 canonname: ?[*:0]u8,
8050 next: ?*addrinfo,
8051};
8052
8053pub const AI = packed struct(u32) {
8054 PASSIVE: bool = false,
8055 CANONNAME: bool = false,
8056 NUMERICHOST: bool = false,
8057 V4MAPPED: bool = false,
8058 ALL: bool = false,
8059 ADDRCONFIG: bool = false,
8060 _6: u4 = 0,
8061 NUMERICSERV: bool = false,
8062 _: u21 = 0,
8063};
8064
8065pub const IPPORT_RESERVED = 1024;
8066
8067pub const IPPROTO = struct {
8068 pub const IP = 0;
8069 pub const HOPOPTS = 0;
8070 pub const ICMP = 1;
8071 pub const IGMP = 2;
8072 pub const IPIP = 4;
8073 pub const TCP = 6;
8074 pub const EGP = 8;
8075 pub const PUP = 12;
8076 pub const UDP = 17;
8077 pub const IDP = 22;
8078 pub const TP = 29;
8079 pub const DCCP = 33;
8080 pub const IPV6 = 41;
8081 pub const ROUTING = 43;
8082 pub const FRAGMENT = 44;
8083 pub const RSVP = 46;
8084 pub const GRE = 47;
8085 pub const ESP = 50;
8086 pub const AH = 51;
8087 pub const ICMPV6 = 58;
8088 pub const NONE = 59;
8089 pub const DSTOPTS = 60;
8090 pub const MTP = 92;
8091 pub const BEETPH = 94;
8092 pub const ENCAP = 98;
8093 pub const PIM = 103;
8094 pub const COMP = 108;
8095 pub const SCTP = 132;
8096 pub const MH = 135;
8097 pub const UDPLITE = 136;
8098 pub const MPLS = 137;
8099 pub const RAW = 255;
8100 pub const MAX = 256;
8101};
8102
8103pub const tcp_repair_opt = extern struct {
8104 opt_code: u32,
8105 opt_val: u32,
8106};
8107
8108pub const tcp_repair_window = extern struct {
8109 snd_wl1: u32,
8110 snd_wnd: u32,
8111 max_window: u32,
8112 rcv_wnd: u32,
8113 rcv_wup: u32,
8114};
8115
8116pub const TcpRepairOption = enum {
8117 TCP_NO_QUEUE,
8118 TCP_RECV_QUEUE,
8119 TCP_SEND_QUEUE,
8120 TCP_QUEUES_NR,
8121};
8122
8123/// why fastopen failed from client perspective
8124pub const tcp_fastopen_client_fail = enum {
8125 /// catch-all
8126 TFO_STATUS_UNSPEC,
8127 /// if not in TFO_CLIENT_NO_COOKIE mode
8128 TFO_COOKIE_UNAVAILABLE,
8129 /// SYN-ACK did not ack SYN data
8130 TFO_DATA_NOT_ACKED,
8131 /// SYN-ACK did not ack SYN data after timeout
8132 TFO_SYN_RETRANSMITTED,
8133};
8134
8135/// for TCP_INFO socket option
8136pub const TCPI_OPT_TIMESTAMPS = 1;
8137pub const TCPI_OPT_SACK = 2;
8138pub const TCPI_OPT_WSCALE = 4;
8139/// ECN was negotiated at TCP session init
8140pub const TCPI_OPT_ECN = 8;
8141/// we received at least one packet with ECT
8142pub const TCPI_OPT_ECN_SEEN = 16;
8143/// SYN-ACK acked data in SYN sent or rcvd
8144pub const TCPI_OPT_SYN_DATA = 32;
8145
8146pub const nfds_t = usize;
8147pub const pollfd = extern struct {
8148 fd: fd_t,
8149 events: i16,
8150 revents: i16 = undefined,
8151};
8152
8153pub const POLL = struct {
8154 pub const IN = 0x001;
8155 pub const PRI = 0x002;
8156 pub const OUT = 0x004;
8157 pub const ERR = 0x008;
8158 pub const HUP = 0x010;
8159 pub const NVAL = 0x020;
8160 pub const RDNORM = 0x040;
8161 pub const RDBAND = 0x080;
8162};
8163
8164pub const HUGETLB_FLAG_ENCODE_SHIFT = 26;
8165pub const HUGETLB_FLAG_ENCODE_MASK = 0x3f;
8166pub const HUGETLB_FLAG_ENCODE_64KB = 16 << HUGETLB_FLAG_ENCODE_SHIFT;
8167pub const HUGETLB_FLAG_ENCODE_512KB = 19 << HUGETLB_FLAG_ENCODE_SHIFT;
8168pub const HUGETLB_FLAG_ENCODE_1MB = 20 << HUGETLB_FLAG_ENCODE_SHIFT;
8169pub const HUGETLB_FLAG_ENCODE_2MB = 21 << HUGETLB_FLAG_ENCODE_SHIFT;
8170pub const HUGETLB_FLAG_ENCODE_8MB = 23 << HUGETLB_FLAG_ENCODE_SHIFT;
8171pub const HUGETLB_FLAG_ENCODE_16MB = 24 << HUGETLB_FLAG_ENCODE_SHIFT;
8172pub const HUGETLB_FLAG_ENCODE_32MB = 25 << HUGETLB_FLAG_ENCODE_SHIFT;
8173pub const HUGETLB_FLAG_ENCODE_256MB = 28 << HUGETLB_FLAG_ENCODE_SHIFT;
8174pub const HUGETLB_FLAG_ENCODE_512MB = 29 << HUGETLB_FLAG_ENCODE_SHIFT;
8175pub const HUGETLB_FLAG_ENCODE_1GB = 30 << HUGETLB_FLAG_ENCODE_SHIFT;
8176pub const HUGETLB_FLAG_ENCODE_2GB = 31 << HUGETLB_FLAG_ENCODE_SHIFT;
8177pub const HUGETLB_FLAG_ENCODE_16GB = 34 << HUGETLB_FLAG_ENCODE_SHIFT;
8178
8179pub const MFD = struct {
8180 pub const CLOEXEC = 0x0001;
8181 pub const ALLOW_SEALING = 0x0002;
8182 pub const HUGETLB = 0x0004;
8183 pub const ALL_FLAGS = CLOEXEC | ALLOW_SEALING | HUGETLB;
8184
8185 pub const HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT;
8186 pub const HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK;
8187 pub const HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB;
8188 pub const HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB;
8189 pub const HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB;
8190 pub const HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB;
8191 pub const HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB;
8192 pub const HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB;
8193 pub const HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB;
8194 pub const HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB;
8195 pub const HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB;
8196 pub const HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB;
8197 pub const HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB;
8198 pub const HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB;
8199};
8200
8201pub const rusage = extern struct {
8202 utime: timeval,
8203 stime: timeval,
8204 maxrss: isize,
8205 ixrss: isize,
8206 idrss: isize,
8207 isrss: isize,
8208 minflt: isize,
8209 majflt: isize,
8210 nswap: isize,
8211 inblock: isize,
8212 oublock: isize,
8213 msgsnd: isize,
8214 msgrcv: isize,
8215 nsignals: isize,
8216 nvcsw: isize,
8217 nivcsw: isize,
8218 __reserved: [16]isize = @splat(0),
8219
8220 pub const SELF = 0;
8221 pub const CHILDREN = -1;
8222 pub const THREAD = 1;
8223};
8224
8225pub const NCC = if (is_ppc) 10 else 8;
8226pub const NCCS = if (is_mips)
8227 23
8228else if (is_sparc)
8229 17
8230else
8231 19;
8232
8233pub const speed_t = if (is_ppc) enum(c_uint) {
8234 B0 = 0x0000000,
8235 B50 = 0x0000001,
8236 B75 = 0x0000002,
8237 B110 = 0x0000003,
8238 B134 = 0x0000004,
8239 B150 = 0x0000005,
8240 B200 = 0x0000006,
8241 B300 = 0x0000007,
8242 B600 = 0x0000008,
8243 B1200 = 0x0000009,
8244 B1800 = 0x000000a,
8245 B2400 = 0x000000b,
8246 B4800 = 0x000000c,
8247 B9600 = 0x000000d,
8248 B19200 = 0x000000e,
8249 B38400 = 0x000000f,
8250
8251 B57600 = 0x00000010,
8252 B115200 = 0x00000011,
8253 B230400 = 0x00000012,
8254 B460800 = 0x00000013,
8255 B500000 = 0x00000014,
8256 B576000 = 0x00000015,
8257 B921600 = 0x00000016,
8258 B1000000 = 0x00000017,
8259 B1152000 = 0x00000018,
8260 B1500000 = 0x00000019,
8261 B2000000 = 0x0000001a,
8262 B2500000 = 0x0000001b,
8263 B3000000 = 0x0000001c,
8264 B3500000 = 0x0000001d,
8265 B4000000 = 0x0000001e,
8266
8267 pub const EXTA = speed_t.B19200;
8268 pub const EXTB = speed_t.B38400;
8269} else if (is_sparc) enum(c_uint) {
8270 B0 = 0x0000000,
8271 B50 = 0x0000001,
8272 B75 = 0x0000002,
8273 B110 = 0x0000003,
8274 B134 = 0x0000004,
8275 B150 = 0x0000005,
8276 B200 = 0x0000006,
8277 B300 = 0x0000007,
8278 B600 = 0x0000008,
8279 B1200 = 0x0000009,
8280 B1800 = 0x000000a,
8281 B2400 = 0x000000b,
8282 B4800 = 0x000000c,
8283 B9600 = 0x000000d,
8284 B19200 = 0x000000e,
8285 B38400 = 0x000000f,
8286
8287 B57600 = 0x00001001,
8288 B115200 = 0x00001002,
8289 B230400 = 0x00001003,
8290 B460800 = 0x00001004,
8291 B76800 = 0x00001005,
8292 B153600 = 0x00001006,
8293 B307200 = 0x00001007,
8294 B614400 = 0x00001008,
8295 B921600 = 0x00001009,
8296 B500000 = 0x0000100a,
8297 B576000 = 0x0000100b,
8298 B1000000 = 0x0000100c,
8299 B1152000 = 0x0000100d,
8300 B1500000 = 0x0000100e,
8301 B2000000 = 0x0000100f,
8302
8303 pub const EXTA = speed_t.B19200;
8304 pub const EXTB = speed_t.B38400;
8305} else enum(c_uint) {
8306 B0 = 0x0000000,
8307 B50 = 0x0000001,
8308 B75 = 0x0000002,
8309 B110 = 0x0000003,
8310 B134 = 0x0000004,
8311 B150 = 0x0000005,
8312 B200 = 0x0000006,
8313 B300 = 0x0000007,
8314 B600 = 0x0000008,
8315 B1200 = 0x0000009,
8316 B1800 = 0x000000a,
8317 B2400 = 0x000000b,
8318 B4800 = 0x000000c,
8319 B9600 = 0x000000d,
8320 B19200 = 0x000000e,
8321 B38400 = 0x000000f,
8322
8323 B57600 = 0x00001001,
8324 B115200 = 0x00001002,
8325 B230400 = 0x00001003,
8326 B460800 = 0x00001004,
8327 B500000 = 0x00001005,
8328 B576000 = 0x00001006,
8329 B921600 = 0x00001007,
8330 B1000000 = 0x00001008,
8331 B1152000 = 0x00001009,
8332 B1500000 = 0x0000100a,
8333 B2000000 = 0x0000100b,
8334 B2500000 = 0x0000100c,
8335 B3000000 = 0x0000100d,
8336 B3500000 = 0x0000100e,
8337 B4000000 = 0x0000100f,
8338
8339 pub const EXTA = speed_t.B19200;
8340 pub const EXTB = speed_t.B38400;
8341};
8342
8343pub const tcflag_t = if (native_arch == .sparc) c_ulong else c_uint;
8344
8345pub const tc_iflag_t = if (is_ppc or native_arch == .alpha) packed struct(tcflag_t) {
8346 IGNBRK: bool = false,
8347 BRKINT: bool = false,
8348 IGNPAR: bool = false,
8349 PARMRK: bool = false,
8350 INPCK: bool = false,
8351 ISTRIP: bool = false,
8352 INLCR: bool = false,
8353 IGNCR: bool = false,
8354 ICRNL: bool = false,
8355 IXON: bool = false,
8356 IXOFF: bool = false,
8357 IXANY: bool = false,
8358 IUCLC: bool = false,
8359 IMAXBEL: bool = false,
8360 IUTF8: bool = false,
8361 _15: u17 = 0,
8362} else packed struct(tcflag_t) {
8363 IGNBRK: bool = false,
8364 BRKINT: bool = false,
8365 IGNPAR: bool = false,
8366 PARMRK: bool = false,
8367 INPCK: bool = false,
8368 ISTRIP: bool = false,
8369 INLCR: bool = false,
8370 IGNCR: bool = false,
8371 ICRNL: bool = false,
8372 IUCLC: bool = false,
8373 IXON: bool = false,
8374 IXANY: bool = false,
8375 IXOFF: bool = false,
8376 IMAXBEL: bool = false,
8377 IUTF8: bool = false,
8378 _15: u17 = 0,
8379};
8380
8381pub const NLDLY = if (is_ppc or native_arch == .alpha) enum(u2) {
8382 NL0 = 0,
8383 NL1 = 1,
8384 NL2 = 2,
8385 NL3 = 3,
8386} else enum(u1) {
8387 NL0 = 0,
8388 NL1 = 1,
8389};
8390
8391pub const CRDLY = enum(u2) {
8392 CR0 = 0,
8393 CR1 = 1,
8394 CR2 = 2,
8395 CR3 = 3,
8396};
8397
8398pub const TABDLY = enum(u2) {
8399 TAB0 = 0,
8400 TAB1 = 1,
8401 TAB2 = 2,
8402 TAB3 = 3,
8403
8404 pub const XTABS = TABDLY.TAB3;
8405};
8406
8407pub const BSDLY = enum(u1) {
8408 BS0 = 0,
8409 BS1 = 1,
8410};
8411
8412pub const VTDLY = enum(u1) {
8413 VT0 = 0,
8414 VT1 = 1,
8415};
8416
8417pub const FFDLY = enum(u1) {
8418 FF0 = 0,
8419 FF1 = 1,
8420};
8421
8422pub const tc_oflag_t = if (is_ppc or native_arch == .alpha) packed struct(tcflag_t) {
8423 OPOST: bool = false,
8424 ONLCR: bool = false,
8425 OLCUC: bool = false,
8426 OCRNL: bool = false,
8427 ONOCR: bool = false,
8428 ONLRET: bool = false,
8429 OFILL: bool = false,
8430 OFDEL: bool = false,
8431 NLDLY: NLDLY = .NL0,
8432 TABDLY: TABDLY = .TAB0,
8433 CRDLY: CRDLY = .CR0,
8434 FFDLY: FFDLY = .FF0,
8435 BSDLY: BSDLY = .BS0,
8436 VTDLY: VTDLY = .VT0,
8437 _17: u15 = 0,
8438} else if (is_sparc) packed struct(tcflag_t) {
8439 OPOST: bool = false,
8440 OLCUC: bool = false,
8441 ONLCR: bool = false,
8442 OCRNL: bool = false,
8443 ONOCR: bool = false,
8444 ONLRET: bool = false,
8445 OFILL: bool = false,
8446 OFDEL: bool = false,
8447 NLDLY: NLDLY = .NL0,
8448 CRDLY: CRDLY = .CR0,
8449 TABDLY: TABDLY = .TAB0,
8450 BSDLY: BSDLY = .BS0,
8451 VTDLY: VTDLY = .VT0,
8452 FFDLY: FFDLY = .FF0,
8453 PAGEOUT: bool = false,
8454 WRAP: bool = false,
8455 _18: u14 = 0,
8456} else packed struct(tcflag_t) {
8457 OPOST: bool = false,
8458 OLCUC: bool = false,
8459 ONLCR: bool = false,
8460 OCRNL: bool = false,
8461 ONOCR: bool = false,
8462 ONLRET: bool = false,
8463 OFILL: bool = false,
8464 OFDEL: bool = false,
8465 NLDLY: NLDLY = .NL0,
8466 CRDLY: CRDLY = .CR0,
8467 TABDLY: TABDLY = .TAB0,
8468 BSDLY: BSDLY = .BS0,
8469 VTDLY: VTDLY = .VT0,
8470 FFDLY: FFDLY = .FF0,
8471 _16: u16 = 0,
8472};
8473
8474pub const CSIZE = enum(u2) {
8475 CS5 = 0,
8476 CS6 = 1,
8477 CS7 = 2,
8478 CS8 = 3,
8479};
8480
8481pub const tc_cflag_t = if (is_ppc or native_arch == .alpha) packed struct(tcflag_t) {
8482 _0: u8 = 0,
8483 CSIZE: CSIZE = .CS5,
8484 CSTOPB: bool = false,
8485 CREAD: bool = false,
8486 PARENB: bool = false,
8487 PARODD: bool = false,
8488 HUPCL: bool = false,
8489 CLOCAL: bool = false,
8490 _16: u13 = 0,
8491 ADDRB: bool = false,
8492 CMSPAR: bool = false,
8493 CRTSCTS: bool = false,
8494} else packed struct(tcflag_t) {
8495 _0: u4 = 0,
8496 CSIZE: CSIZE = .CS5,
8497 CSTOPB: bool = false,
8498 CREAD: bool = false,
8499 PARENB: bool = false,
8500 PARODD: bool = false,
8501 HUPCL: bool = false,
8502 CLOCAL: bool = false,
8503 _12: u17 = 0,
8504 ADDRB: bool = false,
8505 CMSPAR: bool = false,
8506 CRTSCTS: bool = false,
8507};
8508
8509pub const tc_lflag_t = if (is_mips) packed struct(tcflag_t) {
8510 ISIG: bool = false,
8511 ICANON: bool = false,
8512 XCASE: bool = false,
8513 ECHO: bool = false,
8514 ECHOE: bool = false,
8515 ECHOK: bool = false,
8516 ECHONL: bool = false,
8517 NOFLSH: bool = false,
8518 IEXTEN: bool = false,
8519 ECHOCTL: bool = false,
8520 ECHOPRT: bool = false,
8521 ECHOKE: bool = false,
8522 _12: u1 = 0,
8523 FLUSHO: bool = false,
8524 PENDIN: bool = false,
8525 TOSTOP: bool = false,
8526 EXTPROC: bool = false,
8527 _17: u15 = 0,
8528} else if (is_ppc or native_arch == .alpha) packed struct(tcflag_t) {
8529 ECHOKE: bool = false,
8530 ECHOE: bool = false,
8531 ECHOK: bool = false,
8532 ECHO: bool = false,
8533 ECHONL: bool = false,
8534 ECHOPRT: bool = false,
8535 ECHOCTL: bool = false,
8536 ISIG: bool = false,
8537 ICANON: bool = false,
8538 _9: u1 = 0,
8539 IEXTEN: bool = false,
8540 _11: u3 = 0,
8541 XCASE: bool = false,
8542 _15: u7 = 0,
8543 TOSTOP: bool = false,
8544 FLUSHO: bool = false,
8545 _24: u4 = 0,
8546 EXTPROC: bool = false,
8547 PENDIN: bool = false,
8548 _30: u1 = 0,
8549 NOFLSH: bool = false,
8550} else if (is_sparc) packed struct(tcflag_t) {
8551 ISIG: bool = false,
8552 ICANON: bool = false,
8553 XCASE: bool = false,
8554 ECHO: bool = false,
8555 ECHOE: bool = false,
8556 ECHOK: bool = false,
8557 ECHONL: bool = false,
8558 NOFLSH: bool = false,
8559 TOSTOP: bool = false,
8560 ECHOCTL: bool = false,
8561 ECHOPRT: bool = false,
8562 ECHOKE: bool = false,
8563 DEFECHO: bool = false,
8564 FLUSHO: bool = false,
8565 PENDIN: bool = false,
8566 IEXTEN: bool = false,
8567 EXTPROC: bool = false,
8568 _17: u15 = 0,
8569} else packed struct(tcflag_t) {
8570 ISIG: bool = false,
8571 ICANON: bool = false,
8572 XCASE: bool = false,
8573 ECHO: bool = false,
8574 ECHOE: bool = false,
8575 ECHOK: bool = false,
8576 ECHONL: bool = false,
8577 NOFLSH: bool = false,
8578 TOSTOP: bool = false,
8579 ECHOCTL: bool = false,
8580 ECHOPRT: bool = false,
8581 ECHOKE: bool = false,
8582 FLUSHO: bool = false,
8583 _13: u1 = 0,
8584 PENDIN: bool = false,
8585 IEXTEN: bool = false,
8586 EXTPROC: bool = false,
8587 _17: u15 = 0,
8588};
8589
8590pub const cc_t = u8;
8591
8592/// Indices into the `cc` array in the `termios` struct.
8593pub const V = if (is_mips) enum(u32) {
8594 INTR = 0,
8595 QUIT = 1,
8596 ERASE = 2,
8597 KILL = 3,
8598 MIN = 4,
8599 TIME = 5,
8600 EOL2 = 6,
8601 SWTC = 7,
8602 START = 8,
8603 STOP = 9,
8604 SUSP = 10,
8605 REPRINT = 12,
8606 DISCARD = 13,
8607 WERASE = 14,
8608 LNEXT = 15,
8609 EOF = 16,
8610 EOL = 17,
8611} else if (is_ppc) enum(u32) {
8612 INTR = 0,
8613 QUIT = 1,
8614 ERASE = 2,
8615 KILL = 3,
8616 EOF = 4,
8617 MIN = 5,
8618 EOL = 6,
8619 TIME = 7,
8620 EOL2 = 8,
8621 SWTC = 9,
8622 WERASE = 10,
8623 REPRINT = 11,
8624 SUSP = 12,
8625 START = 13,
8626 STOP = 14,
8627 LNEXT = 15,
8628 DISCARD = 16,
8629} else if (native_arch == .alpha) enum(u32) {
8630 EOF = 0,
8631 EOL = 1,
8632 EOL2 = 2,
8633 ERASE = 3,
8634 WERASE = 4,
8635 KILL = 5,
8636 REPRINT = 6,
8637 SWTC = 7,
8638 INTR = 8,
8639 QUIT = 9,
8640 SUSP = 10,
8641 START = 12,
8642 STOP = 13,
8643 LNEXT = 14,
8644 DISCARD = 15,
8645 MIN = 16,
8646 TIME = 17,
8647} else enum(u32) {
8648 INTR = 0,
8649 QUIT = 1,
8650 ERASE = 2,
8651 KILL = 3,
8652 EOF = 4,
8653 TIME = 5,
8654 MIN = 6,
8655 SWTC = 7,
8656 START = 8,
8657 STOP = 9,
8658 SUSP = 10,
8659 EOL = 11,
8660 REPRINT = 12,
8661 DISCARD = 13,
8662 WERASE = 14,
8663 LNEXT = 15,
8664 EOL2 = 16,
8665};
8666
8667pub const TCSA = std.posix.TCSA;
8668
8669pub const sgttyb = if (is_mips or is_ppc or is_sparc) extern struct {
8670 ispeed: c_char,
8671 ospeed: c_char,
8672 erase: c_char,
8673 kill: c_char,
8674 flags: if (is_mips) c_int else c_short,
8675} else void;
8676
8677pub const tchars = if (is_mips or is_ppc or is_sparc or native_arch == .alpha) extern struct {
8678 intrc: c_char,
8679 quitc: c_char,
8680 startc: c_char,
8681 stopc: c_char,
8682 eofc: c_char,
8683 brkc: c_char,
8684} else void;
8685
8686pub const ltchars = if (is_mips or is_ppc or is_sparc or native_arch == .alpha) extern struct {
8687 suspc: c_char,
8688 dsuspc: c_char,
8689 rprntc: c_char,
8690 flushc: c_char,
8691 werasc: c_char,
8692 lnextc: c_char,
8693} else void;
8694
8695pub const termio = extern struct {
8696 iflag: c_ushort,
8697 oflag: c_ushort,
8698 cflag: c_ushort,
8699 lflag: c_ushort,
8700 line: if (is_mips) c_char else u8,
8701 cc: [if (is_mips) NCCS else NCC]u8,
8702};
8703
8704pub const termios = if (is_mips or is_sparc) extern struct {
8705 iflag: tc_iflag_t,
8706 oflag: tc_oflag_t,
8707 cflag: tc_cflag_t,
8708 lflag: tc_lflag_t,
8709 line: cc_t,
8710 cc: [NCCS]cc_t,
8711} else if (is_ppc or native_arch == .alpha) extern struct {
8712 iflag: tc_iflag_t,
8713 oflag: tc_oflag_t,
8714 cflag: tc_cflag_t,
8715 lflag: tc_lflag_t,
8716 cc: [NCCS]cc_t,
8717 line: cc_t,
8718 ispeed: speed_t,
8719 ospeed: speed_t,
8720} else extern struct {
8721 iflag: tc_iflag_t,
8722 oflag: tc_oflag_t,
8723 cflag: tc_cflag_t,
8724 lflag: tc_lflag_t,
8725 line: cc_t,
8726 cc: [NCCS]cc_t,
8727 ispeed: speed_t,
8728 ospeed: speed_t,
8729};
8730
8731pub const termios2 = if (is_mips or native_arch == .alpha) extern struct {
8732 iflag: tc_iflag_t,
8733 oflag: tc_oflag_t,
8734 cflag: tc_cflag_t,
8735 lflag: tc_lflag_t,
8736 cc: [NCCS]cc_t,
8737 line: cc_t,
8738 ispeed: speed_t,
8739 ospeed: speed_t,
8740} else extern struct {
8741 iflag: tc_iflag_t,
8742 oflag: tc_oflag_t,
8743 cflag: tc_cflag_t,
8744 lflag: tc_lflag_t,
8745 line: cc_t,
8746 cc: [NCCS + if (is_sparc) 2 else 0]cc_t,
8747 ispeed: speed_t,
8748 ospeed: speed_t,
8749};
8750
8751/// Linux-specific socket ioctls
8752pub const SIOCINQ = T.FIONREAD;
8753
8754/// Linux-specific socket ioctls
8755/// output queue size (not sent + not acked)
8756pub const SIOCOUTQ = T.IOCOUTQ;
8757
8758pub const SOCK_IOC_TYPE = 0x89;
8759
8760pub const SIOCGSTAMP_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x06, [2]i64);
8761pub const SIOCGSTAMP_OLD = IOCTL.IOR('s', 100, timeval);
8762
8763/// Get stamp (timeval)
8764pub const SIOCGSTAMP = if (native_arch == .x86_64 or @sizeOf(timeval) == 8) SIOCGSTAMP_OLD else SIOCGSTAMP_NEW;
8765
8766pub const SIOCGSTAMPNS_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x07, [2]i64);
8767pub const SIOCGSTAMPNS_OLD = IOCTL.IOR('s', 101, kernel_timespec);
8768
8769/// Get stamp (timespec)
8770pub const SIOCGSTAMPNS = if (native_arch == .x86_64 or @sizeOf(timespec) == 8) SIOCGSTAMPNS_OLD else SIOCGSTAMPNS_NEW;
8771
8772// Routing table calls.
8773/// Add routing table entry
8774pub const SIOCADDRT = 0x890B;
8775
8776/// Delete routing table entry
8777pub const SIOCDELRT = 0x890C;
8778
8779/// Unused
8780pub const SIOCRTMSG = 0x890D;
8781
8782// Socket configuration controls.
8783/// Get iface name
8784pub const SIOCGIFNAME = 0x8910;
8785
8786/// Set iface channel
8787pub const SIOCSIFLINK = 0x8911;
8788
8789/// Get iface list
8790pub const SIOCGIFCONF = 0x8912;
8791
8792/// Get flags
8793pub const SIOCGIFFLAGS = 0x8913;
8794
8795/// Set flags
8796pub const SIOCSIFFLAGS = 0x8914;
8797
8798/// Get PA address
8799pub const SIOCGIFADDR = 0x8915;
8800
8801/// Set PA address
8802pub const SIOCSIFADDR = 0x8916;
8803
8804/// Get remote PA address
8805pub const SIOCGIFDSTADDR = 0x8917;
8806
8807/// Set remote PA address
8808pub const SIOCSIFDSTADDR = 0x8918;
8809
8810/// Get broadcast PA address
8811pub const SIOCGIFBRDADDR = 0x8919;
8812
8813/// Set broadcast PA address
8814pub const SIOCSIFBRDADDR = 0x891a;
8815
8816/// Get network PA mask
8817pub const SIOCGIFNETMASK = 0x891b;
8818
8819/// Set network PA mask
8820pub const SIOCSIFNETMASK = 0x891c;
8821
8822/// Get metric
8823pub const SIOCGIFMETRIC = 0x891d;
8824
8825/// Set metric
8826pub const SIOCSIFMETRIC = 0x891e;
8827
8828/// Get memory address (BSD)
8829pub const SIOCGIFMEM = 0x891f;
8830
8831/// Set memory address (BSD)
8832pub const SIOCSIFMEM = 0x8920;
8833
8834/// Get MTU size
8835pub const SIOCGIFMTU = 0x8921;
8836
8837/// Set MTU size
8838pub const SIOCSIFMTU = 0x8922;
8839
8840/// Set interface name
8841pub const SIOCSIFNAME = 0x8923;
8842
8843/// Set hardware address
8844pub const SIOCSIFHWADDR = 0x8924;
8845
8846/// Get encapsulations
8847pub const SIOCGIFENCAP = 0x8925;
8848
8849/// Set encapsulations
8850pub const SIOCSIFENCAP = 0x8926;
8851
8852/// Get hardware address
8853pub const SIOCGIFHWADDR = 0x8927;
8854
8855/// Driver slaving support
8856pub const SIOCGIFSLAVE = 0x8929;
8857
8858/// Driver slaving support
8859pub const SIOCSIFSLAVE = 0x8930;
8860
8861/// Add to Multicast address lists
8862pub const SIOCADDMULTI = 0x8931;
8863
8864/// Delete from Multicast address lists
8865pub const SIOCDELMULTI = 0x8932;
8866
8867/// name -> if_index mapping
8868pub const SIOCGIFINDEX = 0x8933;
8869
8870/// Set extended flags set
8871pub const SIOCSIFPFLAGS = 0x8934;
8872
8873/// Get extended flags set
8874pub const SIOCGIFPFLAGS = 0x8935;
8875
8876/// Delete PA address
8877pub const SIOCDIFADDR = 0x8936;
8878
8879/// Set hardware broadcast addr
8880pub const SIOCSIFHWBROADCAST = 0x8937;
8881
8882/// Get number of devices
8883pub const SIOCGIFCOUNT = 0x8938;
8884
8885/// Bridging support
8886pub const SIOCGIFBR = 0x8940;
8887
8888/// Set bridging options
8889pub const SIOCSIFBR = 0x8941;
8890
8891/// Get the tx queue length
8892pub const SIOCGIFTXQLEN = 0x8942;
8893
8894/// Set the tx queue length
8895pub const SIOCSIFTXQLEN = 0x8943;
8896
8897/// Ethtool interface
8898pub const SIOCETHTOOL = 0x8946;
8899
8900/// Get address of MII PHY in use.
8901pub const SIOCGMIIPHY = 0x8947;
8902
8903/// Read MII PHY register.
8904pub const SIOCGMIIREG = 0x8948;
8905
8906/// Write MII PHY register.
8907pub const SIOCSMIIREG = 0x8949;
8908
8909/// Get / Set netdev parameters
8910pub const SIOCWANDEV = 0x894A;
8911
8912/// Output queue size (not sent only)
8913pub const SIOCOUTQNSD = 0x894B;
8914
8915/// Get socket network namespace
8916pub const SIOCGSKNS = 0x894C;
8917
8918// ARP cache control calls.
8919// 0x8950 - 0x8952 obsolete calls.
8920/// Delete ARP table entry
8921pub const SIOCDARP = 0x8953;
8922
8923/// Get ARP table entry
8924pub const SIOCGARP = 0x8954;
8925
8926/// Set ARP table entry
8927pub const SIOCSARP = 0x8955;
8928
8929// RARP cache control calls.
8930/// Delete RARP table entry
8931pub const SIOCDRARP = 0x8960;
8932
8933/// Get RARP table entry
8934pub const SIOCGRARP = 0x8961;
8935
8936/// Set RARP table entry
8937pub const SIOCSRARP = 0x8962;
8938
8939// Driver configuration calls
8940/// Get device parameters
8941pub const SIOCGIFMAP = 0x8970;
8942
8943/// Set device parameters
8944pub const SIOCSIFMAP = 0x8971;
8945
8946// DLCI configuration calls
8947/// Create new DLCI device
8948pub const SIOCADDDLCI = 0x8980;
8949
8950/// Delete DLCI device
8951pub const SIOCDELDLCI = 0x8981;
8952
8953/// 802.1Q VLAN support
8954pub const SIOCGIFVLAN = 0x8982;
8955
8956/// Set 802.1Q VLAN options
8957pub const SIOCSIFVLAN = 0x8983;
8958
8959// bonding calls
8960/// Enslave a device to the bond
8961pub const SIOCBONDENSLAVE = 0x8990;
8962
8963/// Release a slave from the bond
8964pub const SIOCBONDRELEASE = 0x8991;
8965
8966/// Set the hw addr of the bond
8967pub const SIOCBONDSETHWADDR = 0x8992;
8968
8969/// rtn info about slave state
8970pub const SIOCBONDSLAVEINFOQUERY = 0x8993;
8971
8972/// rtn info about bond state
8973pub const SIOCBONDINFOQUERY = 0x8994;
8974
8975/// Update to a new active slave
8976pub const SIOCBONDCHANGEACTIVE = 0x8995;
8977
8978// Bridge calls
8979/// Create new bridge device
8980pub const SIOCBRADDBR = 0x89a0;
8981
8982/// Remove bridge device
8983pub const SIOCBRDELBR = 0x89a1;
8984
8985/// Add interface to bridge
8986pub const SIOCBRADDIF = 0x89a2;
8987
8988/// Remove interface from bridge
8989pub const SIOCBRDELIF = 0x89a3;
8990
8991/// Get hardware time stamp config
8992pub const SIOCSHWTSTAMP = 0x89b0;
8993
8994/// Set hardware time stamp config
8995pub const SIOCGHWTSTAMP = 0x89b1;
8996
8997/// Device private ioctl calls
8998pub const SIOCDEVPRIVATE = 0x89F0;
8999
9000/// These 16 ioctl calls are protocol private
9001pub const SIOCPROTOPRIVATE = 0x89E0;
9002
9003pub const IFNAMESIZE = 16;
9004
9005pub const IFF = packed struct(u16) {
9006 UP: bool = false,
9007 BROADCAST: bool = false,
9008 DEBUG: bool = false,
9009 LOOPBACK: bool = false,
9010 POINTOPOINT: bool = false,
9011 NOTRAILERS: bool = false,
9012 RUNNING: bool = false,
9013 NOARP: bool = false,
9014 PROMISC: bool = false,
9015 _9: u7 = 0,
9016};
9017
9018pub const ifmap = extern struct {
9019 mem_start: usize,
9020 mem_end: usize,
9021 base_addr: u16,
9022 irq: u8,
9023 dma: u8,
9024 port: u8,
9025};
9026
9027pub const ifreq = extern struct {
9028 ifrn: extern union {
9029 name: [IFNAMESIZE]u8,
9030 },
9031 ifru: extern union {
9032 addr: sockaddr,
9033 dstaddr: sockaddr,
9034 broadaddr: sockaddr,
9035 netmask: sockaddr,
9036 hwaddr: sockaddr,
9037 flags: IFF,
9038 ivalue: i32,
9039 mtu: i32,
9040 map: ifmap,
9041 slave: [IFNAMESIZE - 1:0]u8,
9042 newname: [IFNAMESIZE - 1:0]u8,
9043 data: ?[*]u8,
9044 },
9045};
9046
9047pub const PACKET = struct {
9048 pub const HOST = 0;
9049 pub const BROADCAST = 1;
9050 pub const MULTICAST = 2;
9051 pub const OTHERHOST = 3;
9052 pub const OUTGOING = 4;
9053 pub const LOOPBACK = 5;
9054 pub const USER = 6;
9055 pub const KERNEL = 7;
9056
9057 pub const ADD_MEMBERSHIP = 1;
9058 pub const DROP_MEMBERSHIP = 2;
9059 pub const RECV_OUTPUT = 3;
9060 pub const RX_RING = 5;
9061 pub const STATISTICS = 6;
9062 pub const COPY_THRESH = 7;
9063 pub const AUXDATA = 8;
9064 pub const ORIGDEV = 9;
9065 pub const VERSION = 10;
9066 pub const HDRLEN = 11;
9067 pub const RESERVE = 12;
9068 pub const TX_RING = 13;
9069 pub const LOSS = 14;
9070 pub const VNET_HDR = 15;
9071 pub const TX_TIMESTAMP = 16;
9072 pub const TIMESTAMP = 17;
9073 pub const FANOUT = 18;
9074 pub const TX_HAS_OFF = 19;
9075 pub const QDISC_BYPASS = 20;
9076 pub const ROLLOVER_STATS = 21;
9077 pub const FANOUT_DATA = 22;
9078 pub const IGNORE_OUTGOING = 23;
9079 pub const VNET_HDR_SZ = 24;
9080
9081 pub const FANOUT_HASH = 0;
9082 pub const FANOUT_LB = 1;
9083 pub const FANOUT_CPU = 2;
9084 pub const FANOUT_ROLLOVER = 3;
9085 pub const FANOUT_RND = 4;
9086 pub const FANOUT_QM = 5;
9087 pub const FANOUT_CBPF = 6;
9088 pub const FANOUT_EBPF = 7;
9089 pub const FANOUT_FLAG_ROLLOVER = 0x1000;
9090 pub const FANOUT_FLAG_UNIQUEID = 0x2000;
9091 pub const FANOUT_FLAG_IGNORE_OUTGOING = 0x4000;
9092 pub const FANOUT_FLAG_DEFRAG = 0x8000;
9093};
9094
9095pub const tpacket_versions = enum(u32) {
9096 V1 = 0,
9097 V2 = 1,
9098 V3 = 2,
9099};
9100
9101pub const tpacket_req3 = extern struct {
9102 block_size: c_uint, // Minimal size of contiguous block
9103 block_nr: c_uint, // Number of blocks
9104 frame_size: c_uint, // Size of frame
9105 frame_nr: c_uint, // Total number of frames
9106 retire_blk_tov: c_uint, // Timeout in msecs
9107 sizeof_priv: c_uint, // Offset to private data area
9108 feature_req_word: c_uint,
9109};
9110
9111pub const tpacket_bd_ts = extern struct {
9112 sec: c_uint,
9113 frac: extern union {
9114 usec: c_uint,
9115 nsec: c_uint,
9116 },
9117};
9118
9119pub const TP_STATUS = extern union {
9120 rx: packed struct(u32) {
9121 USER: bool,
9122 COPY: bool,
9123 LOSING: bool,
9124 CSUMNOTREADY: bool,
9125 VLAN_VALID: bool,
9126 BLK_TMO: bool,
9127 VLAN_TPID_VALID: bool,
9128 CSUM_VALID: bool,
9129 GSO_TCP: bool,
9130 _: u20,
9131 TS_SOFTWARE: bool,
9132 TS_SYS_HARDWARE: bool,
9133 TS_RAW_HARDWARE: bool,
9134 },
9135 tx: packed struct(u32) {
9136 SEND_REQUEST: bool,
9137 SENDING: bool,
9138 WRONG_FORMAT: bool,
9139 _: u26,
9140 TS_SOFTWARE: bool,
9141 TS_SYS_HARDWARE: bool,
9142 TS_RAW_HARDWARE: bool,
9143 },
9144};
9145
9146pub const tpacket_hdr_v1 = extern struct {
9147 block_status: TP_STATUS,
9148 num_pkts: u32,
9149 offset_to_first_pkt: u32,
9150 blk_len: u32,
9151 seq_num: u64 align(8),
9152 ts_first_pkt: tpacket_bd_ts,
9153 ts_last_pkt: tpacket_bd_ts,
9154};
9155
9156pub const tpacket_bd_header_u = extern union {
9157 bh1: tpacket_hdr_v1,
9158};
9159
9160pub const tpacket_block_desc = extern struct {
9161 version: u32,
9162 offset_to_priv: u32,
9163 hdr: tpacket_bd_header_u,
9164};
9165
9166pub const tpacket_hdr_variant1 = extern struct {
9167 rxhash: u32,
9168 vlan_tci: u32,
9169 vlan_tpid: u16,
9170 padding: u16,
9171};
9172
9173pub const tpacket3_hdr = extern struct {
9174 next_offset: u32,
9175 sec: u32,
9176 nsec: u32,
9177 snaplen: u32,
9178 len: u32,
9179 status: u32,
9180 mac: u16,
9181 net: u16,
9182 variant: extern union {
9183 hv1: tpacket_hdr_variant1,
9184 },
9185 padding: [8]u8,
9186};
9187
9188pub const tpacket_stats_v3 = extern struct {
9189 packets: c_uint,
9190 drops: c_uint,
9191 freeze_q_cnt: c_uint,
9192};
9193
9194// doc comments copied from musl
9195pub const rlimit_resource = if (native_arch.isMIPS()) enum(c_int) {
9196 /// Per-process CPU limit, in seconds.
9197 CPU = 0,
9198
9199 /// Largest file that can be created, in bytes.
9200 FSIZE = 1,
9201
9202 /// Maximum size of data segment, in bytes.
9203 DATA = 2,
9204
9205 /// Maximum size of stack segment, in bytes.
9206 STACK = 3,
9207
9208 /// Largest core file that can be created, in bytes.
9209 CORE = 4,
9210
9211 /// Number of open files.
9212 NOFILE = 5,
9213
9214 /// Address space limit.
9215 AS = 6,
9216
9217 /// Largest resident set size, in bytes.
9218 /// This affects swapping; processes that are exceeding their
9219 /// resident set size will be more likely to have physical memory
9220 /// taken from them.
9221 RSS = 7,
9222
9223 /// Number of processes.
9224 NPROC = 8,
9225
9226 /// Locked-in-memory address space.
9227 MEMLOCK = 9,
9228
9229 /// Maximum number of file locks.
9230 LOCKS = 10,
9231
9232 /// Maximum number of pending signals.
9233 SIGPENDING = 11,
9234
9235 /// Maximum bytes in POSIX message queues.
9236 MSGQUEUE = 12,
9237
9238 /// Maximum nice priority allowed to raise to.
9239 /// Nice levels 19 .. -20 correspond to 0 .. 39
9240 /// values of this resource limit.
9241 NICE = 13,
9242
9243 /// Maximum realtime priority allowed for non-privileged
9244 /// processes.
9245 RTPRIO = 14,
9246
9247 /// Maximum CPU time in µs that a process scheduled under a real-time
9248 /// scheduling policy may consume without making a blocking system
9249 /// call before being forcibly descheduled.
9250 RTTIME = 15,
9251
9252 _,
9253} else if (native_arch.isSPARC()) enum(c_int) {
9254 /// Per-process CPU limit, in seconds.
9255 CPU = 0,
9256
9257 /// Largest file that can be created, in bytes.
9258 FSIZE = 1,
9259
9260 /// Maximum size of data segment, in bytes.
9261 DATA = 2,
9262
9263 /// Maximum size of stack segment, in bytes.
9264 STACK = 3,
9265
9266 /// Largest core file that can be created, in bytes.
9267 CORE = 4,
9268
9269 /// Largest resident set size, in bytes.
9270 /// This affects swapping; processes that are exceeding their
9271 /// resident set size will be more likely to have physical memory
9272 /// taken from them.
9273 RSS = 5,
9274
9275 /// Number of open files.
9276 NOFILE = 6,
9277
9278 /// Number of processes.
9279 NPROC = 7,
9280
9281 /// Locked-in-memory address space.
9282 MEMLOCK = 8,
9283
9284 /// Address space limit.
9285 AS = 9,
9286
9287 /// Maximum number of file locks.
9288 LOCKS = 10,
9289
9290 /// Maximum number of pending signals.
9291 SIGPENDING = 11,
9292
9293 /// Maximum bytes in POSIX message queues.
9294 MSGQUEUE = 12,
9295
9296 /// Maximum nice priority allowed to raise to.
9297 /// Nice levels 19 .. -20 correspond to 0 .. 39
9298 /// values of this resource limit.
9299 NICE = 13,
9300
9301 /// Maximum realtime priority allowed for non-privileged
9302 /// processes.
9303 RTPRIO = 14,
9304
9305 /// Maximum CPU time in µs that a process scheduled under a real-time
9306 /// scheduling policy may consume without making a blocking system
9307 /// call before being forcibly descheduled.
9308 RTTIME = 15,
9309
9310 _,
9311} else if (native_arch == .alpha) enum(c_int) {
9312 /// Per-process CPU limit, in seconds.
9313 CPU = 0,
9314 /// Largest file that can be created, in bytes.
9315 FSIZE = 1,
9316 /// Maximum size of data segment, in bytes.
9317 DATA = 2,
9318 /// Maximum size of stack segment, in bytes.
9319 STACK = 3,
9320 /// Largest core file that can be created, in bytes.
9321 CORE = 4,
9322 /// Largest resident set size, in bytes.
9323 /// This affects swapping; processes that are exceeding their
9324 /// resident set size will be more likely to have physical memory
9325 /// taken from them.
9326 RSS = 5,
9327 /// Number of open files.
9328 NOFILE = 6,
9329 /// Address space limit.
9330 AS = 7,
9331 /// Number of processes.
9332 NPROC = 8,
9333 /// Locked-in-memory address space.
9334 MEMLOCK = 9,
9335 /// Maximum number of file locks.
9336 LOCKS = 10,
9337 /// Maximum number of pending signals.
9338 SIGPENDING = 11,
9339 /// Maximum bytes in POSIX message queues.
9340 MSGQUEUE = 12,
9341 /// Maximum nice priority allowed to raise to.
9342 /// Nice levels 19 .. -20 correspond to 0 .. 39
9343 /// values of this resource limit.
9344 NICE = 13,
9345 /// Maximum realtime priority allowed for non-privileged
9346 /// processes.
9347 RTPRIO = 14,
9348 /// Maximum CPU time in µs that a process scheduled under a real-time
9349 /// scheduling policy may consume without making a blocking system
9350 /// call before being forcibly descheduled.
9351 RTTIME = 15,
9352
9353 _,
9354} else enum(c_int) {
9355 /// Per-process CPU limit, in seconds.
9356 CPU = 0,
9357 /// Largest file that can be created, in bytes.
9358 FSIZE = 1,
9359 /// Maximum size of data segment, in bytes.
9360 DATA = 2,
9361 /// Maximum size of stack segment, in bytes.
9362 STACK = 3,
9363 /// Largest core file that can be created, in bytes.
9364 CORE = 4,
9365 /// Largest resident set size, in bytes.
9366 /// This affects swapping; processes that are exceeding their
9367 /// resident set size will be more likely to have physical memory
9368 /// taken from them.
9369 RSS = 5,
9370 /// Number of processes.
9371 NPROC = 6,
9372 /// Number of open files.
9373 NOFILE = 7,
9374 /// Locked-in-memory address space.
9375 MEMLOCK = 8,
9376 /// Address space limit.
9377 AS = 9,
9378 /// Maximum number of file locks.
9379 LOCKS = 10,
9380 /// Maximum number of pending signals.
9381 SIGPENDING = 11,
9382 /// Maximum bytes in POSIX message queues.
9383 MSGQUEUE = 12,
9384 /// Maximum nice priority allowed to raise to.
9385 /// Nice levels 19 .. -20 correspond to 0 .. 39
9386 /// values of this resource limit.
9387 NICE = 13,
9388 /// Maximum realtime priority allowed for non-privileged
9389 /// processes.
9390 RTPRIO = 14,
9391 /// Maximum CPU time in µs that a process scheduled under a real-time
9392 /// scheduling policy may consume without making a blocking system
9393 /// call before being forcibly descheduled.
9394 RTTIME = 15,
9395
9396 _,
9397};
9398
9399pub const rlim_t = u64;
9400
9401pub const RLIM = struct {
9402 /// No limit
9403 pub const INFINITY: rlim_t = if (native_arch == .alpha)
9404 ~@as(u63, 0)
9405 else
9406 ~@as(rlim_t, 0);
9407
9408 pub const SAVED_MAX = INFINITY;
9409 pub const SAVED_CUR = INFINITY;
9410};
9411
9412pub const rlimit = extern struct {
9413 /// Soft limit
9414 cur: rlim_t,
9415 /// Hard limit
9416 max: rlim_t,
9417};
9418
9419pub const MADV = struct {
9420 pub const NORMAL = 0;
9421 pub const RANDOM = 1;
9422 pub const SEQUENTIAL = 2;
9423 pub const WILLNEED = 3;
9424 pub const DONTNEED = 4;
9425 pub const FREE = 8;
9426 pub const REMOVE = 9;
9427 pub const DONTFORK = 10;
9428 pub const DOFORK = 11;
9429 pub const MERGEABLE = 12;
9430 pub const UNMERGEABLE = 13;
9431 pub const HUGEPAGE = 14;
9432 pub const NOHUGEPAGE = 15;
9433 pub const DONTDUMP = 16;
9434 pub const DODUMP = 17;
9435 pub const WIPEONFORK = 18;
9436 pub const KEEPONFORK = 19;
9437 pub const COLD = 20;
9438 pub const PAGEOUT = 21;
9439 pub const HWPOISON = 100;
9440 pub const SOFT_OFFLINE = 101;
9441};
9442
9443pub const POSIX_FADV = switch (native_arch) {
9444 .s390x => if (@typeInfo(usize).int.bits == 64) struct {
9445 pub const NORMAL = 0;
9446 pub const RANDOM = 1;
9447 pub const SEQUENTIAL = 2;
9448 pub const WILLNEED = 3;
9449 pub const DONTNEED = 6;
9450 pub const NOREUSE = 7;
9451 } else struct {
9452 pub const NORMAL = 0;
9453 pub const RANDOM = 1;
9454 pub const SEQUENTIAL = 2;
9455 pub const WILLNEED = 3;
9456 pub const DONTNEED = 4;
9457 pub const NOREUSE = 5;
9458 },
9459 else => struct {
9460 pub const NORMAL = 0;
9461 pub const RANDOM = 1;
9462 pub const SEQUENTIAL = 2;
9463 pub const WILLNEED = 3;
9464 pub const DONTNEED = 4;
9465 pub const NOREUSE = 5;
9466 },
9467};
9468
9469pub const timeval = extern struct {
9470 sec: isize,
9471 usec: i64,
9472};
9473
9474pub const timezone = extern struct {
9475 minuteswest: i32,
9476 dsttime: i32,
9477};
9478
9479/// The timespec struct used by the kernel.
9480pub const kernel_timespec = extern struct {
9481 sec: i64,
9482 nsec: i64,
9483
9484 /// For use with `utimensat` and `futimens`.
9485 pub const NOW: timespec = .{
9486 .sec = 0,
9487 .nsec = 0x3fffffff,
9488 };
9489
9490 /// For use with `utimensat` and `futimens`.
9491 pub const OMIT: timespec = .{
9492 .sec = 0,
9493 .nsec = 0x3ffffffe,
9494 };
9495};
9496
9497/// For use with `utimensat` and `futimens`.
9498pub const UTIME = struct {
9499 pub const NOW: timespec = .{ .sec = 0, .nsec = 0x3fffffff };
9500 pub const OMIT: timespec = .{ .sec = 0, .nsec = 0x3ffffffe };
9501};
9502
9503// https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877
9504const use_kernel_timespec = native_arch == .hexagon or native_arch == .riscv32 or switch (native_abi) {
9505 .gnux32, .muslx32, .x32 => true,
9506 else => false,
9507};
9508pub const timespec = if (use_kernel_timespec) kernel_timespec else extern struct {
9509 sec: isize,
9510 nsec: isize,
9511};
9512
9513pub const XDP = struct {
9514 pub const SHARED_UMEM = (1 << 0);
9515 pub const COPY = (1 << 1);
9516 pub const ZEROCOPY = (1 << 2);
9517 pub const UMEM_UNALIGNED_CHUNK_FLAG = (1 << 0);
9518 pub const USE_NEED_WAKEUP = (1 << 3);
9519
9520 pub const MMAP_OFFSETS = 1;
9521 pub const RX_RING = 2;
9522 pub const TX_RING = 3;
9523 pub const UMEM_REG = 4;
9524 pub const UMEM_FILL_RING = 5;
9525 pub const UMEM_COMPLETION_RING = 6;
9526 pub const STATISTICS = 7;
9527 pub const OPTIONS = 8;
9528
9529 pub const OPTIONS_ZEROCOPY = (1 << 0);
9530
9531 pub const PGOFF_RX_RING = 0;
9532 pub const PGOFF_TX_RING = 0x80000000;
9533 pub const UMEM_PGOFF_FILL_RING = 0x100000000;
9534 pub const UMEM_PGOFF_COMPLETION_RING = 0x180000000;
9535};
9536
9537pub const xdp_ring_offset = extern struct {
9538 producer: u64,
9539 consumer: u64,
9540 desc: u64,
9541 flags: u64,
9542};
9543
9544pub const xdp_mmap_offsets = extern struct {
9545 rx: xdp_ring_offset,
9546 tx: xdp_ring_offset,
9547 fr: xdp_ring_offset,
9548 cr: xdp_ring_offset,
9549};
9550
9551pub const xdp_umem_reg = extern struct {
9552 addr: u64,
9553 len: u64,
9554 chunk_size: u32,
9555 headroom: u32,
9556 flags: u32,
9557};
9558
9559pub const xdp_statistics = extern struct {
9560 rx_dropped: u64,
9561 rx_invalid_descs: u64,
9562 tx_invalid_descs: u64,
9563 rx_ring_full: u64,
9564 rx_fill_ring_empty_descs: u64,
9565 tx_ring_empty_descs: u64,
9566};
9567
9568pub const xdp_options = extern struct {
9569 flags: u32,
9570};
9571
9572pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48;
9573pub const XSK_UNALIGNED_BUF_ADDR_MASK = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1;
9574
9575pub const xdp_desc = extern struct {
9576 addr: u64,
9577 len: u32,
9578 options: u32,
9579};
9580
9581fn issecure_mask(comptime x: comptime_int) comptime_int {
9582 return 1 << x;
9583}
9584
9585pub const SECUREBITS_DEFAULT = 0x00000000;
9586
9587pub const SECURE_NOROOT = 0;
9588pub const SECURE_NOROOT_LOCKED = 1;
9589
9590pub const SECBIT_NOROOT = issecure_mask(SECURE_NOROOT);
9591pub const SECBIT_NOROOT_LOCKED = issecure_mask(SECURE_NOROOT_LOCKED);
9592
9593pub const SECURE_NO_SETUID_FIXUP = 2;
9594pub const SECURE_NO_SETUID_FIXUP_LOCKED = 3;
9595
9596pub const SECBIT_NO_SETUID_FIXUP = issecure_mask(SECURE_NO_SETUID_FIXUP);
9597pub const SECBIT_NO_SETUID_FIXUP_LOCKED = issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED);
9598
9599pub const SECURE_KEEP_CAPS = 4;
9600pub const SECURE_KEEP_CAPS_LOCKED = 5;
9601
9602pub const SECBIT_KEEP_CAPS = issecure_mask(SECURE_KEEP_CAPS);
9603pub const SECBIT_KEEP_CAPS_LOCKED = issecure_mask(SECURE_KEEP_CAPS_LOCKED);
9604
9605pub const SECURE_NO_CAP_AMBIENT_RAISE = 6;
9606pub const SECURE_NO_CAP_AMBIENT_RAISE_LOCKED = 7;
9607
9608pub const SECBIT_NO_CAP_AMBIENT_RAISE = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
9609pub const SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED = issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED);
9610
9611pub const SECURE_ALL_BITS = issecure_mask(SECURE_NOROOT) |
9612 issecure_mask(SECURE_NO_SETUID_FIXUP) |
9613 issecure_mask(SECURE_KEEP_CAPS) |
9614 issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE);
9615pub const SECURE_ALL_LOCKS = SECURE_ALL_BITS << 1;
9616
9617pub const PR = enum(i32) {
9618 SET_PDEATHSIG = 1,
9619 GET_PDEATHSIG = 2,
9620
9621 GET_DUMPABLE = 3,
9622 SET_DUMPABLE = 4,
9623
9624 GET_UNALIGN = 5,
9625 SET_UNALIGN = 6,
9626
9627 GET_KEEPCAPS = 7,
9628 SET_KEEPCAPS = 8,
9629
9630 GET_FPEMU = 9,
9631 SET_FPEMU = 10,
9632
9633 GET_FPEXC = 11,
9634 SET_FPEXC = 12,
9635
9636 GET_TIMING = 13,
9637 SET_TIMING = 14,
9638
9639 SET_NAME = 15,
9640 GET_NAME = 16,
9641
9642 GET_ENDIAN = 19,
9643 SET_ENDIAN = 20,
9644
9645 GET_SECCOMP = 21,
9646 SET_SECCOMP = 22,
9647
9648 CAPBSET_READ = 23,
9649 CAPBSET_DROP = 24,
9650
9651 GET_TSC = 25,
9652 SET_TSC = 26,
9653
9654 GET_SECUREBITS = 27,
9655 SET_SECUREBITS = 28,
9656
9657 SET_TIMERSLACK = 29,
9658 GET_TIMERSLACK = 30,
9659
9660 TASK_PERF_EVENTS_DISABLE = 31,
9661 TASK_PERF_EVENTS_ENABLE = 32,
9662
9663 MCE_KILL = 33,
9664
9665 MCE_KILL_GET = 34,
9666
9667 SET_MM = 35,
9668
9669 SET_PTRACER = 0x59616d61,
9670
9671 SET_CHILD_SUBREAPER = 36,
9672 GET_CHILD_SUBREAPER = 37,
9673
9674 SET_NO_NEW_PRIVS = 38,
9675 GET_NO_NEW_PRIVS = 39,
9676
9677 GET_TID_ADDRESS = 40,
9678
9679 SET_THP_DISABLE = 41,
9680 GET_THP_DISABLE = 42,
9681
9682 MPX_ENABLE_MANAGEMENT = 43,
9683 MPX_DISABLE_MANAGEMENT = 44,
9684
9685 SET_FP_MODE = 45,
9686 GET_FP_MODE = 46,
9687
9688 CAP_AMBIENT = 47,
9689
9690 SVE_SET_VL = 50,
9691 SVE_GET_VL = 51,
9692
9693 GET_SPECULATION_CTRL = 52,
9694 SET_SPECULATION_CTRL = 53,
9695
9696 _,
9697
9698 pub const UNALIGN_NOPRINT = 1;
9699 pub const UNALIGN_SIGBUS = 2;
9700
9701 pub const FPEMU_NOPRINT = 1;
9702 pub const FPEMU_SIGFPE = 2;
9703
9704 pub const FP_EXC_SW_ENABLE = 0x80;
9705 pub const FP_EXC_DIV = 0x010000;
9706 pub const FP_EXC_OVF = 0x020000;
9707 pub const FP_EXC_UND = 0x040000;
9708 pub const FP_EXC_RES = 0x080000;
9709 pub const FP_EXC_INV = 0x100000;
9710 pub const FP_EXC_DISABLED = 0;
9711 pub const FP_EXC_NONRECOV = 1;
9712 pub const FP_EXC_ASYNC = 2;
9713 pub const FP_EXC_PRECISE = 3;
9714
9715 pub const TIMING_STATISTICAL = 0;
9716 pub const TIMING_TIMESTAMP = 1;
9717
9718 pub const ENDIAN_BIG = 0;
9719 pub const ENDIAN_LITTLE = 1;
9720 pub const ENDIAN_PPC_LITTLE = 2;
9721
9722 pub const TSC_ENABLE = 1;
9723 pub const TSC_SIGSEGV = 2;
9724
9725 pub const MCE_KILL_CLEAR = 0;
9726 pub const MCE_KILL_SET = 1;
9727
9728 pub const MCE_KILL_LATE = 0;
9729 pub const MCE_KILL_EARLY = 1;
9730 pub const MCE_KILL_DEFAULT = 2;
9731
9732 pub const SET_MM_START_CODE = 1;
9733 pub const SET_MM_END_CODE = 2;
9734 pub const SET_MM_START_DATA = 3;
9735 pub const SET_MM_END_DATA = 4;
9736 pub const SET_MM_START_STACK = 5;
9737 pub const SET_MM_START_BRK = 6;
9738 pub const SET_MM_BRK = 7;
9739 pub const SET_MM_ARG_START = 8;
9740 pub const SET_MM_ARG_END = 9;
9741 pub const SET_MM_ENV_START = 10;
9742 pub const SET_MM_ENV_END = 11;
9743 pub const SET_MM_AUXV = 12;
9744 pub const SET_MM_EXE_FILE = 13;
9745 pub const SET_MM_MAP = 14;
9746 pub const SET_MM_MAP_SIZE = 15;
9747
9748 pub const SET_PTRACER_ANY = maxInt(c_ulong);
9749
9750 pub const FP_MODE_FR = 1 << 0;
9751 pub const FP_MODE_FRE = 1 << 1;
9752
9753 pub const CAP_AMBIENT_IS_SET = 1;
9754 pub const CAP_AMBIENT_RAISE = 2;
9755 pub const CAP_AMBIENT_LOWER = 3;
9756 pub const CAP_AMBIENT_CLEAR_ALL = 4;
9757
9758 pub const SVE_SET_VL_ONEXEC = 1 << 18;
9759 pub const SVE_VL_LEN_MASK = 0xffff;
9760 pub const SVE_VL_INHERIT = 1 << 17;
9761
9762 pub const SPEC_STORE_BYPASS = 0;
9763 pub const SPEC_NOT_AFFECTED = 0;
9764 pub const SPEC_PRCTL = 1 << 0;
9765 pub const SPEC_ENABLE = 1 << 1;
9766 pub const SPEC_DISABLE = 1 << 2;
9767 pub const SPEC_FORCE_DISABLE = 1 << 3;
9768};
9769
9770pub const prctl_mm_map = extern struct {
9771 start_code: u64,
9772 end_code: u64,
9773 start_data: u64,
9774 end_data: u64,
9775 start_brk: u64,
9776 brk: u64,
9777 start_stack: u64,
9778 arg_start: u64,
9779 arg_end: u64,
9780 env_start: u64,
9781 env_end: u64,
9782 auxv: *u64,
9783 auxv_size: u32,
9784 exe_fd: u32,
9785};
9786
9787pub const NETLINK = struct {
9788 /// Routing/device hook
9789 pub const ROUTE = 0;
9790
9791 /// Unused number
9792 pub const UNUSED = 1;
9793
9794 /// Reserved for user mode socket protocols
9795 pub const USERSOCK = 2;
9796
9797 /// Unused number, formerly ip_queue
9798 pub const FIREWALL = 3;
9799
9800 /// socket monitoring
9801 pub const SOCK_DIAG = 4;
9802
9803 /// netfilter/iptables ULOG
9804 pub const NFLOG = 5;
9805
9806 /// ipsec
9807 pub const XFRM = 6;
9808
9809 /// SELinux event notifications
9810 pub const SELINUX = 7;
9811
9812 /// Open-iSCSI
9813 pub const ISCSI = 8;
9814
9815 /// auditing
9816 pub const AUDIT = 9;
9817
9818 pub const FIB_LOOKUP = 10;
9819
9820 pub const CONNECTOR = 11;
9821
9822 /// netfilter subsystem
9823 pub const NETFILTER = 12;
9824
9825 pub const IP6_FW = 13;
9826
9827 /// DECnet routing messages
9828 pub const DNRTMSG = 14;
9829
9830 /// Kernel messages to userspace
9831 pub const KOBJECT_UEVENT = 15;
9832
9833 pub const GENERIC = 16;
9834
9835 // leave room for NETLINK_DM (DM Events)
9836
9837 /// SCSI Transports
9838 pub const SCSITRANSPORT = 18;
9839
9840 pub const ECRYPTFS = 19;
9841
9842 pub const RDMA = 20;
9843
9844 /// Crypto layer
9845 pub const CRYPTO = 21;
9846
9847 /// SMC monitoring
9848 pub const SMC = 22;
9849};
9850
9851// Flags values
9852
9853/// It is request message.
9854pub const NLM_F_REQUEST = 0x01;
9855
9856/// Multipart message, terminated by NLMSG_DONE
9857pub const NLM_F_MULTI = 0x02;
9858
9859/// Reply with ack, with zero or error code
9860pub const NLM_F_ACK = 0x04;
9861
9862/// Echo this request
9863pub const NLM_F_ECHO = 0x08;
9864
9865/// Dump was inconsistent due to sequence change
9866pub const NLM_F_DUMP_INTR = 0x10;
9867
9868/// Dump was filtered as requested
9869pub const NLM_F_DUMP_FILTERED = 0x20;
9870
9871// Modifiers to GET request
9872
9873/// specify tree root
9874pub const NLM_F_ROOT = 0x100;
9875
9876/// return all matching
9877pub const NLM_F_MATCH = 0x200;
9878
9879/// atomic GET
9880pub const NLM_F_ATOMIC = 0x400;
9881pub const NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH;
9882
9883// Modifiers to NEW request
9884
9885/// Override existing
9886pub const NLM_F_REPLACE = 0x100;
9887
9888/// Do not touch, if it exists
9889pub const NLM_F_EXCL = 0x200;
9890
9891/// Create, if it does not exist
9892pub const NLM_F_CREATE = 0x400;
9893
9894/// Add to end of list
9895pub const NLM_F_APPEND = 0x800;
9896
9897// Modifiers to DELETE request
9898
9899/// Do not delete recursively
9900pub const NLM_F_NONREC = 0x100;
9901
9902// Flags for ACK message
9903
9904/// request was capped
9905pub const NLM_F_CAPPED = 0x100;
9906
9907/// extended ACK TVLs were included
9908pub const NLM_F_ACK_TLVS = 0x200;
9909
9910pub const NetlinkMessageType = enum(u16) {
9911 /// < 0x10: reserved control messages
9912 pub const MIN_TYPE = 0x10;
9913
9914 /// Nothing.
9915 NOOP = 0x1,
9916
9917 /// Error
9918 ERROR = 0x2,
9919
9920 /// End of a dump
9921 DONE = 0x3,
9922
9923 /// Data lost
9924 OVERRUN = 0x4,
9925
9926 // rtlink types
9927
9928 RTM_NEWLINK = 16,
9929 RTM_DELLINK,
9930 RTM_GETLINK,
9931 RTM_SETLINK,
9932
9933 RTM_NEWADDR = 20,
9934 RTM_DELADDR,
9935 RTM_GETADDR,
9936
9937 RTM_NEWROUTE = 24,
9938 RTM_DELROUTE,
9939 RTM_GETROUTE,
9940
9941 RTM_NEWNEIGH = 28,
9942 RTM_DELNEIGH,
9943 RTM_GETNEIGH,
9944
9945 RTM_NEWRULE = 32,
9946 RTM_DELRULE,
9947 RTM_GETRULE,
9948
9949 RTM_NEWQDISC = 36,
9950 RTM_DELQDISC,
9951 RTM_GETQDISC,
9952
9953 RTM_NEWTCLASS = 40,
9954 RTM_DELTCLASS,
9955 RTM_GETTCLASS,
9956
9957 RTM_NEWTFILTER = 44,
9958 RTM_DELTFILTER,
9959 RTM_GETTFILTER,
9960
9961 RTM_NEWACTION = 48,
9962 RTM_DELACTION,
9963 RTM_GETACTION,
9964
9965 RTM_NEWPREFIX = 52,
9966
9967 RTM_GETMULTICAST = 58,
9968
9969 RTM_GETANYCAST = 62,
9970
9971 RTM_NEWNEIGHTBL = 64,
9972 RTM_GETNEIGHTBL = 66,
9973 RTM_SETNEIGHTBL,
9974
9975 RTM_NEWNDUSEROPT = 68,
9976
9977 RTM_NEWADDRLABEL = 72,
9978 RTM_DELADDRLABEL,
9979 RTM_GETADDRLABEL,
9980
9981 RTM_GETDCB = 78,
9982 RTM_SETDCB,
9983
9984 RTM_NEWNETCONF = 80,
9985 RTM_DELNETCONF,
9986 RTM_GETNETCONF = 82,
9987
9988 RTM_NEWMDB = 84,
9989 RTM_DELMDB = 85,
9990 RTM_GETMDB = 86,
9991
9992 RTM_NEWNSID = 88,
9993 RTM_DELNSID = 89,
9994 RTM_GETNSID = 90,
9995
9996 RTM_NEWSTATS = 92,
9997 RTM_GETSTATS = 94,
9998
9999 RTM_NEWCACHEREPORT = 96,
10000
10001 RTM_NEWCHAIN = 100,
10002 RTM_DELCHAIN,
10003 RTM_GETCHAIN,
10004
10005 RTM_NEWNEXTHOP = 104,
10006 RTM_DELNEXTHOP,
10007 RTM_GETNEXTHOP,
10008
10009 _,
10010};
10011
10012/// Netlink message header
10013/// Specified in RFC 3549 Section 2.3.2
10014pub const nlmsghdr = extern struct {
10015 /// Length of message including header
10016 len: u32,
10017
10018 /// Message content
10019 type: NetlinkMessageType,
10020
10021 /// Additional flags
10022 flags: u16,
10023
10024 /// Sequence number
10025 seq: u32,
10026
10027 /// Sending process port ID
10028 pid: u32,
10029};
10030
10031pub const ifinfomsg = extern struct {
10032 family: u8,
10033 __pad1: u8 = 0,
10034
10035 /// ARPHRD_*
10036 type: c_ushort,
10037
10038 /// Link index
10039 index: c_int,
10040
10041 /// IFF_* flags
10042 flags: c_uint,
10043
10044 /// IFF_* change mask
10045 change: c_uint,
10046};
10047
10048pub const rtattr = extern struct {
10049 /// Length of option
10050 len: c_ushort,
10051
10052 /// Type of option
10053 type: extern union {
10054 /// IFLA_* from linux/if_link.h
10055 link: IFLA,
10056 /// IFA_* from linux/if_addr.h
10057 addr: IFA,
10058 },
10059
10060 pub const ALIGNTO = 4;
10061};
10062
10063pub const IFA = enum(c_ushort) {
10064 UNSPEC,
10065 ADDRESS,
10066 LOCAL,
10067 LABEL,
10068 BROADCAST,
10069 ANYCAST,
10070 CACHEINFO,
10071 MULTICAST,
10072 FLAGS,
10073 RT_PRIORITY,
10074 TARGET_NETNSID,
10075 PROTO,
10076
10077 _,
10078};
10079
10080pub const IFLA = enum(c_ushort) {
10081 UNSPEC,
10082 ADDRESS,
10083 BROADCAST,
10084 IFNAME,
10085 MTU,
10086 LINK,
10087 QDISC,
10088 STATS,
10089 COST,
10090 PRIORITY,
10091 MASTER,
10092
10093 /// Wireless Extension event
10094 WIRELESS,
10095
10096 /// Protocol specific information for a link
10097 PROTINFO,
10098
10099 TXQLEN,
10100 MAP,
10101 WEIGHT,
10102 OPERSTATE,
10103 LINKMODE,
10104 LINKINFO,
10105 NET_NS_PID,
10106 IFALIAS,
10107
10108 /// Number of VFs if device is SR-IOV PF
10109 NUM_VF,
10110
10111 VFINFO_LIST,
10112 STATS64,
10113 VF_PORTS,
10114 PORT_SELF,
10115 AF_SPEC,
10116
10117 /// Group the device belongs to
10118 GROUP,
10119
10120 NET_NS_FD,
10121
10122 /// Extended info mask, VFs, etc
10123 EXT_MASK,
10124
10125 /// Promiscuity count: > 0 means acts PROMISC
10126 PROMISCUITY,
10127
10128 NUM_TX_QUEUES,
10129 NUM_RX_QUEUES,
10130 CARRIER,
10131 PHYS_PORT_ID,
10132 CARRIER_CHANGES,
10133 PHYS_SWITCH_ID,
10134 LINK_NETNSID,
10135 PHYS_PORT_NAME,
10136 PROTO_DOWN,
10137 GSO_MAX_SEGS,
10138 GSO_MAX_SIZE,
10139 PAD,
10140 XDP,
10141 EVENT,
10142
10143 NEW_NETNSID,
10144 IF_NETNSID,
10145
10146 CARRIER_UP_COUNT,
10147 CARRIER_DOWN_COUNT,
10148 NEW_IFINDEX,
10149 MIN_MTU,
10150 MAX_MTU,
10151
10152 _,
10153
10154 pub const TARGET_NETNSID: IFLA = .IF_NETNSID;
10155};
10156
10157pub const rtnl_link_ifmap = extern struct {
10158 mem_start: u64,
10159 mem_end: u64,
10160 base_addr: u64,
10161 irq: u16,
10162 dma: u8,
10163 port: u8,
10164};
10165
10166pub const rtnl_link_stats = extern struct {
10167 /// total packets received
10168 rx_packets: u32,
10169
10170 /// total packets transmitted
10171 tx_packets: u32,
10172
10173 /// total bytes received
10174 rx_bytes: u32,
10175
10176 /// total bytes transmitted
10177 tx_bytes: u32,
10178
10179 /// bad packets received
10180 rx_errors: u32,
10181
10182 /// packet transmit problems
10183 tx_errors: u32,
10184
10185 /// no space in linux buffers
10186 rx_dropped: u32,
10187
10188 /// no space available in linux
10189 tx_dropped: u32,
10190
10191 /// multicast packets received
10192 multicast: u32,
10193
10194 collisions: u32,
10195
10196 // detailed rx_errors
10197
10198 rx_length_errors: u32,
10199
10200 /// receiver ring buff overflow
10201 rx_over_errors: u32,
10202
10203 /// recved pkt with crc error
10204 rx_crc_errors: u32,
10205
10206 /// recv'd frame alignment error
10207 rx_frame_errors: u32,
10208
10209 /// recv'r fifo overrun
10210 rx_fifo_errors: u32,
10211
10212 /// receiver missed packet
10213 rx_missed_errors: u32,
10214
10215 // detailed tx_errors
10216 tx_aborted_errors: u32,
10217 tx_carrier_errors: u32,
10218 tx_fifo_errors: u32,
10219 tx_heartbeat_errors: u32,
10220 tx_window_errors: u32,
10221
10222 // for cslip etc
10223
10224 rx_compressed: u32,
10225 tx_compressed: u32,
10226
10227 /// dropped, no handler found
10228 rx_nohandler: u32,
10229};
10230
10231pub const rtnl_link_stats64 = extern struct {
10232 /// total packets received
10233 rx_packets: u64,
10234
10235 /// total packets transmitted
10236 tx_packets: u64,
10237
10238 /// total bytes received
10239 rx_bytes: u64,
10240
10241 /// total bytes transmitted
10242 tx_bytes: u64,
10243
10244 /// bad packets received
10245 rx_errors: u64,
10246
10247 /// packet transmit problems
10248 tx_errors: u64,
10249
10250 /// no space in linux buffers
10251 rx_dropped: u64,
10252
10253 /// no space available in linux
10254 tx_dropped: u64,
10255
10256 /// multicast packets received
10257 multicast: u64,
10258
10259 collisions: u64,
10260
10261 // detailed rx_errors
10262
10263 rx_length_errors: u64,
10264
10265 /// receiver ring buff overflow
10266 rx_over_errors: u64,
10267
10268 /// recved pkt with crc error
10269 rx_crc_errors: u64,
10270
10271 /// recv'd frame alignment error
10272 rx_frame_errors: u64,
10273
10274 /// recv'r fifo overrun
10275 rx_fifo_errors: u64,
10276
10277 /// receiver missed packet
10278 rx_missed_errors: u64,
10279
10280 // detailed tx_errors
10281 tx_aborted_errors: u64,
10282 tx_carrier_errors: u64,
10283 tx_fifo_errors: u64,
10284 tx_heartbeat_errors: u64,
10285 tx_window_errors: u64,
10286
10287 // for cslip etc
10288
10289 rx_compressed: u64,
10290 tx_compressed: u64,
10291
10292 /// dropped, no handler found
10293 rx_nohandler: u64,
10294};
10295
10296pub const perf_event_attr = extern struct {
10297 /// Major type: hardware/software/tracepoint/etc.
10298 type: PERF.TYPE = undefined,
10299 /// Size of the attr structure, for fwd/bwd compat.
10300 size: u32 = @sizeOf(perf_event_attr),
10301 /// Type specific configuration information.
10302 config: u64 = 0,
10303
10304 sample_period_or_freq: u64 = 0,
10305 sample_type: u64 = 0,
10306 read_format: u64 = 0,
10307
10308 flags: packed struct(u64) {
10309 /// off by default
10310 disabled: bool = false,
10311 /// children inherit it
10312 inherit: bool = false,
10313 /// must always be on PMU
10314 pinned: bool = false,
10315 /// only group on PMU
10316 exclusive: bool = false,
10317 /// don't count user
10318 exclude_user: bool = false,
10319 /// ditto kernel
10320 exclude_kernel: bool = false,
10321 /// ditto hypervisor
10322 exclude_hv: bool = false,
10323 /// don't count when idle
10324 exclude_idle: bool = false,
10325 /// include mmap data
10326 mmap: bool = false,
10327 /// include comm data
10328 comm: bool = false,
10329 /// use freq, not period
10330 freq: bool = false,
10331 /// per task counts
10332 inherit_stat: bool = false,
10333 /// next exec enables
10334 enable_on_exec: bool = false,
10335 /// trace fork/exit
10336 task: bool = false,
10337 /// wakeup_watermark
10338 watermark: bool = false,
10339 /// precise_ip:
10340 ///
10341 /// 0 - SAMPLE_IP can have arbitrary skid
10342 /// 1 - SAMPLE_IP must have constant skid
10343 /// 2 - SAMPLE_IP requested to have 0 skid
10344 /// 3 - SAMPLE_IP must have 0 skid
10345 ///
10346 /// See also PERF_RECORD_MISC_EXACT_IP
10347 /// skid constraint
10348 precise_ip: u2 = 0,
10349 /// non-exec mmap data
10350 mmap_data: bool = false,
10351 /// sample_type all events
10352 sample_id_all: bool = false,
10353
10354 /// don't count in host
10355 exclude_host: bool = false,
10356 /// don't count in guest
10357 exclude_guest: bool = false,
10358
10359 /// exclude kernel callchains
10360 exclude_callchain_kernel: bool = false,
10361 /// exclude user callchains
10362 exclude_callchain_user: bool = false,
10363 /// include mmap with inode data
10364 mmap2: bool = false,
10365 /// flag comm events that are due to an exec
10366 comm_exec: bool = false,
10367 /// use @clockid for time fields
10368 use_clockid: bool = false,
10369 /// context switch data
10370 context_switch: bool = false,
10371 /// Write ring buffer from end to beginning
10372 write_backward: bool = false,
10373 /// include namespaces data
10374 namespaces: bool = false,
10375 /// include ksymbol events
10376 ksymbol: bool = false,
10377 /// include BPF events
10378 bpf_event: bool = false,
10379 /// generate AUX records instead of events
10380 aux_output: bool = false,
10381 /// include cgroup events
10382 cgroup: bool = false,
10383 /// include text poke events
10384 text_poke: bool = false,
10385 /// use build ID in mmap2 events
10386 build_id: bool = false,
10387 /// children only inherit if cloned with CLONE_THREAD
10388 inherit_thread: bool = false,
10389 /// event is removed from task on exec
10390 remove_on_exec: bool = false,
10391 /// send synchronous SIGTRAP on event
10392 sigtrap: bool = false,
10393
10394 __reserved_1: u26 = 0,
10395 } = .{},
10396 /// wakeup every n events, or
10397 /// bytes before wakeup
10398 wakeup_events_or_watermark: u32 = 0,
10399
10400 bp_type: u32 = 0,
10401
10402 /// This field is also used for:
10403 /// bp_addr
10404 /// kprobe_func for perf_kprobe
10405 /// uprobe_path for perf_uprobe
10406 config1: u64 = 0,
10407 /// This field is also used for:
10408 /// bp_len
10409 /// kprobe_addr when kprobe_func == null
10410 /// probe_offset for perf_[k,u]probe
10411 config2: u64 = 0,
10412
10413 /// enum perf_branch_sample_type
10414 branch_sample_type: u64 = 0,
10415
10416 /// Defines set of user regs to dump on samples.
10417 /// See asm/perf_regs.h for details.
10418 sample_regs_user: u64 = 0,
10419
10420 /// Defines size of the user stack to dump on samples.
10421 sample_stack_user: u32 = 0,
10422
10423 clockid: clockid_t = .REALTIME,
10424 /// Defines set of regs to dump for each sample
10425 /// state captured on:
10426 /// - precise = 0: PMU interrupt
10427 /// - precise > 0: sampled instruction
10428 ///
10429 /// See asm/perf_regs.h for details.
10430 sample_regs_intr: u64 = 0,
10431
10432 /// Wakeup watermark for AUX area
10433 aux_watermark: u32 = 0,
10434 sample_max_stack: u16 = 0,
10435 /// Align to u64
10436 __reserved_2: u16 = 0,
10437
10438 aux_sample_size: u32 = 0,
10439 aux_action: packed struct(u32) {
10440 /// start AUX area tracing paused
10441 start_paused: bool = false,
10442 /// on overflow, pause AUX area tracing
10443 pause: bool = false,
10444 /// on overflow, resume AUX area tracing
10445 @"resume": bool = false,
10446
10447 __reserved_3: u29 = 0,
10448 } = .{},
10449
10450 /// User provided data if sigtrap == true
10451 sig_data: u64 = 0,
10452
10453 /// Extension of config2
10454 config3: u64 = 0,
10455};
10456
10457pub const perf_event_header = extern struct {
10458 /// Event type: sample/mmap/fork/etc.
10459 type: PERF.RECORD,
10460 /// Additional informations on the event: kernel/user/hypervisor/etc.
10461 misc: packed struct(u16) {
10462 cpu_mode: PERF.RECORD.MISC.CPU_MODE,
10463 _: u9,
10464 PROC_MAP_PARSE_TIMEOUT: bool,
10465 bit13: packed union {
10466 MMAP_DATA: bool,
10467 COMM_EXEC: bool,
10468 FORK_EXEC: bool,
10469 SWITCH_OUT: bool,
10470 },
10471 bit14: packed union {
10472 EXACT_IP: bool,
10473 SWITCH_OUT_PREEMPT: bool,
10474 MMAP_BUILD_ID: bool,
10475 },
10476 EXT_RESERVED: bool,
10477 },
10478 /// Size of the following record
10479 size: u16,
10480};
10481
10482pub const perf_event_mmap_page = extern struct {
10483 /// Version number of this struct
10484 version: u32,
10485 /// Lowest version this is compatible with
10486 compt_version: u32,
10487 /// Seqlock for synchronization
10488 lock: u32,
10489 /// Hardware counter identifier
10490 index: u32,
10491 /// Add to hardware counter value
10492 offset: i64,
10493 /// Time the event was active
10494 time_enabled: u64,
10495 /// Time the event was running
10496 time_running: u64,
10497 capabilities: packed struct(u64) {
10498 /// If kernel version < 3.12
10499 /// this rapresents both user_rdpmc and user_time (user_rdpmc | user_time)
10500 /// otherwise deprecated.
10501 bit0: bool,
10502 /// Set if bit0 is deprecated
10503 bit0_is_deprecated: bool,
10504 /// Hardware support for userspace read of performance counters
10505 user_rdpmc: bool,
10506 /// Hardware support for a constant non stop timestamp counter (Eg. TSC on x86)
10507 user_time: bool,
10508 /// The time_zero field is used
10509 user_time_zero: bool,
10510 /// The time_{cycle,mask} fields are used
10511 user_time_short: bool,
10512 ____res: u58,
10513 },
10514 /// If capabilities.user_rdpmc
10515 /// this field reports the bit-width of the value read with rdpmc() or equivalent
10516 pcm_width: u16,
10517 /// If capabilities.user_time the following fields can be used to compute the time
10518 /// delta since time_enabled (in ns) using RDTSC or similar
10519 time_shift: u16,
10520 time_mult: u32,
10521 time_offset: u64,
10522 /// If capabilities.user_time_zero the hardware clock can be calculated from
10523 /// sample timestamps
10524 time_zero: u64,
10525 /// Header size
10526 size: u32,
10527 __reserved_1: u32,
10528 /// The following fields are used to compute the timestamp when the hardware clock
10529 /// is less than 64bit wide
10530 time_cycles: u64,
10531 time_mask: u64,
10532 __reserved: [116 * 8]u8,
10533 /// Head in the data section
10534 data_head: u64,
10535 /// Userspace written tail
10536 data_tail: u64,
10537 /// Where the buffer starts
10538 data_offset: u64,
10539 /// Data buffer size
10540 data_size: u64,
10541 // if aux is used, head in the data section
10542 aux_head: u64,
10543 // if aux is used, userspace written tail
10544 aux_tail: u64,
10545 // if aux is used, where the buffer starts
10546 aux_offset: u64,
10547 // if aux is used, data buffer size
10548 aux_size: u64,
10549};
10550
10551pub const PERF = struct {
10552 pub const TYPE = enum(u32) {
10553 HARDWARE,
10554 SOFTWARE,
10555 TRACEPOINT,
10556 HW_CACHE,
10557 RAW,
10558 BREAKPOINT,
10559 MAX,
10560 _,
10561 };
10562
10563 pub const COUNT = struct {
10564 pub const HW = enum(u32) {
10565 CPU_CYCLES,
10566 INSTRUCTIONS,
10567 CACHE_REFERENCES,
10568 CACHE_MISSES,
10569 BRANCH_INSTRUCTIONS,
10570 BRANCH_MISSES,
10571 BUS_CYCLES,
10572 STALLED_CYCLES_FRONTEND,
10573 STALLED_CYCLES_BACKEND,
10574 REF_CPU_CYCLES,
10575 MAX,
10576
10577 pub const CACHE = enum(u32) {
10578 L1D,
10579 L1I,
10580 LL,
10581 DTLB,
10582 ITLB,
10583 BPU,
10584 NODE,
10585 MAX,
10586
10587 pub const OP = enum(u32) {
10588 READ,
10589 WRITE,
10590 PREFETCH,
10591 MAX,
10592 };
10593
10594 pub const RESULT = enum(u32) {
10595 ACCESS,
10596 MISS,
10597 MAX,
10598 };
10599 };
10600 };
10601
10602 pub const SW = enum(u32) {
10603 CPU_CLOCK,
10604 TASK_CLOCK,
10605 PAGE_FAULTS,
10606 CONTEXT_SWITCHES,
10607 CPU_MIGRATIONS,
10608 PAGE_FAULTS_MIN,
10609 PAGE_FAULTS_MAJ,
10610 ALIGNMENT_FAULTS,
10611 EMULATION_FAULTS,
10612 DUMMY,
10613 BPF_OUTPUT,
10614 MAX,
10615 };
10616 };
10617
10618 pub const SAMPLE = struct {
10619 pub const IP = 1;
10620 pub const TID = 2;
10621 pub const TIME = 4;
10622 pub const ADDR = 8;
10623 pub const READ = 16;
10624 pub const CALLCHAIN = 32;
10625 pub const ID = 64;
10626 pub const CPU = 128;
10627 pub const PERIOD = 256;
10628 pub const STREAM_ID = 512;
10629 pub const RAW = 1024;
10630 pub const BRANCH_STACK = 2048;
10631 pub const REGS_USER = 4096;
10632 pub const STACK_USER = 8192;
10633 pub const WEIGHT = 16384;
10634 pub const DATA_SRC = 32768;
10635 pub const IDENTIFIER = 65536;
10636 pub const TRANSACTION = 131072;
10637 pub const REGS_INTR = 262144;
10638 pub const PHYS_ADDR = 524288;
10639 pub const MAX = 1048576;
10640
10641 pub const BRANCH = struct {
10642 pub const USER = 1 << 0;
10643 pub const KERNEL = 1 << 1;
10644 pub const HV = 1 << 2;
10645 pub const ANY = 1 << 3;
10646 pub const ANY_CALL = 1 << 4;
10647 pub const ANY_RETURN = 1 << 5;
10648 pub const IND_CALL = 1 << 6;
10649 pub const ABORT_TX = 1 << 7;
10650 pub const IN_TX = 1 << 8;
10651 pub const NO_TX = 1 << 9;
10652 pub const COND = 1 << 10;
10653 pub const CALL_STACK = 1 << 11;
10654 pub const IND_JUMP = 1 << 12;
10655 pub const CALL = 1 << 13;
10656 pub const NO_FLAGS = 1 << 14;
10657 pub const NO_CYCLES = 1 << 15;
10658 pub const TYPE_SAVE = 1 << 16;
10659 pub const MAX = 1 << 17;
10660 };
10661 };
10662
10663 pub const RECORD = enum(u32) {
10664 MMAP = 1,
10665 LOST = 2,
10666 COMM = 3,
10667 EXIT = 4,
10668 THROTTLE = 5,
10669 UNTHROTTLE = 6,
10670 FORK = 7,
10671 READ = 8,
10672 SAMPLE = 9,
10673 MMAP2 = 10,
10674 AUX = 11,
10675 ITRACE_START = 12,
10676 LOST_SAMPLES = 13,
10677 SWITCH = 14,
10678 SWITCH_CPU_WIDE = 15,
10679 NAMESPACES = 16,
10680 KSYMBOL = 17,
10681 BPF_EVENT = 18,
10682 CGROUP = 19,
10683 TEXT_POKE = 20,
10684 AUX_OUTPUT_HW_ID = 21,
10685
10686 const MISC = struct {
10687 pub const CPU_MODE = enum(u3) {
10688 UNKNOWN = 0,
10689 KERNEL = 1,
10690 USER = 2,
10691 HYPERVISOR = 3,
10692 GUEST_KERNEL = 4,
10693 GUEST_USER = 5,
10694 };
10695 };
10696 };
10697
10698 pub const FLAG = struct {
10699 pub const FD_NO_GROUP = 1 << 0;
10700 pub const FD_OUTPUT = 1 << 1;
10701 pub const PID_CGROUP = 1 << 2;
10702 pub const FD_CLOEXEC = 1 << 3;
10703 };
10704
10705 pub const EVENT_IOC = struct {
10706 pub const ENABLE = 9216;
10707 pub const DISABLE = 9217;
10708 pub const REFRESH = 9218;
10709 pub const RESET = 9219;
10710 pub const PERIOD = 1074275332;
10711 pub const SET_OUTPUT = 9221;
10712 pub const SET_FILTER = 1074275334;
10713 pub const ID = 2148017159;
10714 pub const SET_BPF = 1074013192;
10715 pub const PAUSE_OUTPUT = 1074013193;
10716 pub const QUERY_BPF = 3221758986;
10717 pub const MODIFY_ATTRIBUTES = 1074275339;
10718 };
10719
10720 pub const IOC_FLAG_GROUP = 1;
10721};
10722
10723// TODO: Add the rest of the AUDIT defines?
10724pub const AUDIT = struct {
10725 pub const ARCH = enum(u32) {
10726 const CONVENTION_MIPS64_N32 = 0x20000000;
10727 const @"64BIT" = 0x80000000;
10728 const LE = 0x40000000;
10729
10730 AARCH64 = toAudit(.AARCH64, @"64BIT" | LE),
10731 ALPHA = toAudit(.ALPHA, @"64BIT" | LE),
10732 ARCOMPACT = toAudit(.ARC_COMPACT, LE),
10733 ARCOMPACTBE = toAudit(.ARC_COMPACT, 0),
10734 ARCV2 = toAudit(.ARC_COMPACT2, LE),
10735 ARCV2BE = toAudit(.ARC_COMPACT2, 0),
10736 ARM = toAudit(.ARM, LE),
10737 ARMEB = toAudit(.ARM, 0),
10738 C6X = toAudit(.TI_C6000, LE),
10739 C6XBE = toAudit(.TI_C6000, 0),
10740 CRIS = toAudit(.CRIS, LE),
10741 CSKY = toAudit(.CSKY, LE),
10742 FRV = toAudit(.FRV, 0),
10743 H8300 = toAudit(.H8_300, 0),
10744 HEXAGON = toAudit(.HEXAGON, 0),
10745 I386 = toAudit(.@"386", LE),
10746 IA64 = toAudit(.IA_64, @"64BIT" | LE),
10747 M32R = toAudit(.M32R, 0),
10748 M68K = toAudit(.@"68K", 0),
10749 MICROBLAZE = toAudit(.MICROBLAZE, 0),
10750 MIPS = toAudit(.MIPS, 0),
10751 MIPSEL = toAudit(.MIPS, LE),
10752 MIPS64 = toAudit(.MIPS, @"64BIT"),
10753 MIPS64N32 = toAudit(.MIPS, @"64BIT" | CONVENTION_MIPS64_N32),
10754 MIPSEL64 = toAudit(.MIPS, @"64BIT" | LE),
10755 MIPSEL64N32 = toAudit(.MIPS, @"64BIT" | LE | CONVENTION_MIPS64_N32),
10756 NDS32 = toAudit(.NDS32, LE),
10757 NDS32BE = toAudit(.NDS32, 0),
10758 NIOS2 = toAudit(.ALTERA_NIOS2, LE),
10759 OPENRISC = toAudit(.OPENRISC, 0),
10760 PARISC = toAudit(.PARISC, 0),
10761 PARISC64 = toAudit(.PARISC, @"64BIT"),
10762 PPC = toAudit(.PPC, 0),
10763 PPC64 = toAudit(.PPC64, @"64BIT"),
10764 PPC64LE = toAudit(.PPC64, @"64BIT" | LE),
10765 RISCV32 = toAudit(.RISCV, LE),
10766 RISCV64 = toAudit(.RISCV, @"64BIT" | LE),
10767 S390 = toAudit(.S390, 0),
10768 S390X = toAudit(.S390, @"64BIT"),
10769 SH = toAudit(.SH, 0),
10770 SHEL = toAudit(.SH, LE),
10771 SH64 = toAudit(.SH, @"64BIT"),
10772 SHEL64 = toAudit(.SH, @"64BIT" | LE),
10773 SPARC = toAudit(.SPARC, 0),
10774 SPARC64 = toAudit(.SPARCV9, @"64BIT"),
10775 TILEGX = toAudit(.TILEGX, @"64BIT" | LE),
10776 TILEGX32 = toAudit(.TILEGX, LE),
10777 TILEPRO = toAudit(.TILEPRO, LE),
10778 UNICORE = toAudit(.UNICORE, LE),
10779 X86_64 = toAudit(.X86_64, @"64BIT" | LE),
10780 XTENSA = toAudit(.XTENSA, 0),
10781 LOONGARCH32 = toAudit(.LOONGARCH, LE),
10782 LOONGARCH64 = toAudit(.LOONGARCH, @"64BIT" | LE),
10783
10784 fn toAudit(em: elf.EM, flags: u32) u32 {
10785 return @backingInt(em) | flags;
10786 }
10787
10788 pub const current: AUDIT.ARCH = switch (native_arch) {
10789 .arm, .thumb => .ARM,
10790 .armeb, .thumbeb => .ARMEB,
10791 .aarch64 => .AARCH64,
10792 .arc => .ARCV2,
10793 .arceb => .ARCV2BE,
10794 .csky => .CSKY,
10795 .hexagon => .HEXAGON,
10796 .loongarch32 => .LOONGARCH32,
10797 .loongarch64 => .LOONGARCH64,
10798 .m68k => .M68K,
10799 .microblaze, .microblazeel => .MICROBLAZE,
10800 .mips => .MIPS,
10801 .mipsel => .MIPSEL,
10802 .mips64 => switch (native_abi) {
10803 .gnuabin32, .muslabin32, .abin32 => .MIPS64N32,
10804 else => .MIPS64,
10805 },
10806 .mips64el => switch (native_abi) {
10807 .gnuabin32, .muslabin32, .abin32 => .MIPSEL64N32,
10808 else => .MIPSEL64,
10809 },
10810 .or1k => .OPENRISC,
10811 .powerpc => .PPC,
10812 .powerpc64 => .PPC64,
10813 .powerpc64le => .PPC64LE,
10814 .riscv32 => .RISCV32,
10815 .riscv64 => .RISCV64,
10816 .s390x => .S390X,
10817 .sh => .SHEL,
10818 .sheb => .SH,
10819 .sparc => .SPARC,
10820 .sparc64 => .SPARC64,
10821 .x86 => .I386,
10822 .x86_64 => .X86_64,
10823 .xtensa => .XTENSA,
10824 else => @compileError("unsupported architecture"),
10825 };
10826 };
10827};
10828
10829pub const PTRACE = struct {
10830 pub const TRACEME = 0;
10831 pub const PEEKTEXT = 1;
10832 pub const PEEKDATA = 2;
10833 pub const PEEKUSER = 3;
10834 pub const POKETEXT = 4;
10835 pub const POKEDATA = 5;
10836 pub const POKEUSER = 6;
10837 pub const CONT = 7;
10838 pub const KILL = 8;
10839 pub const SINGLESTEP = 9;
10840 pub const GETREGS = 12;
10841 pub const SETREGS = 13;
10842 pub const GETFPREGS = 14;
10843 pub const SETFPREGS = 15;
10844 pub const ATTACH = 16;
10845 pub const DETACH = 17;
10846 pub const GETFPXREGS = 18;
10847 pub const SETFPXREGS = 19;
10848 pub const SYSCALL = 24;
10849 pub const SETOPTIONS = 0x4200;
10850 pub const GETEVENTMSG = 0x4201;
10851 pub const GETSIGINFO = 0x4202;
10852 pub const SETSIGINFO = 0x4203;
10853 pub const GETREGSET = 0x4204;
10854 pub const SETREGSET = 0x4205;
10855 pub const SEIZE = 0x4206;
10856 pub const INTERRUPT = 0x4207;
10857 pub const LISTEN = 0x4208;
10858 pub const PEEKSIGINFO = 0x4209;
10859 pub const GETSIGMASK = 0x420a;
10860 pub const SETSIGMASK = 0x420b;
10861 pub const SECCOMP_GET_FILTER = 0x420c;
10862 pub const SECCOMP_GET_METADATA = 0x420d;
10863 pub const GET_SYSCALL_INFO = 0x420e;
10864
10865 pub const EVENT = struct {
10866 pub const FORK = 1;
10867 pub const VFORK = 2;
10868 pub const CLONE = 3;
10869 pub const EXEC = 4;
10870 pub const VFORK_DONE = 5;
10871 pub const EXIT = 6;
10872 pub const SECCOMP = 7;
10873 pub const STOP = 128;
10874 };
10875
10876 pub const O = struct {
10877 pub const TRACESYSGOOD = 1;
10878 pub const TRACEFORK = 1 << PTRACE.EVENT.FORK;
10879 pub const TRACEVFORK = 1 << PTRACE.EVENT.VFORK;
10880 pub const TRACECLONE = 1 << PTRACE.EVENT.CLONE;
10881 pub const TRACEEXEC = 1 << PTRACE.EVENT.EXEC;
10882 pub const TRACEVFORKDONE = 1 << PTRACE.EVENT.VFORK_DONE;
10883 pub const TRACEEXIT = 1 << PTRACE.EVENT.EXIT;
10884 pub const TRACESECCOMP = 1 << PTRACE.EVENT.SECCOMP;
10885
10886 pub const EXITKILL = 1 << 20;
10887 pub const SUSPEND_SECCOMP = 1 << 21;
10888
10889 pub const MASK = 0x000000ff | PTRACE.O.EXITKILL | PTRACE.O.SUSPEND_SECCOMP;
10890 };
10891};
10892
10893/// For futex2_waitv and futex2_requeue. Arrays of `futex2_waitone` allow
10894/// waiting on multiple futexes in one call.
10895pub const futex2_waitone = extern struct {
10896 /// Expected value at uaddr, should match size of futex.
10897 val: u64,
10898 /// User address to wait on. Top-bits must be 0 on 32-bit.
10899 uaddr: u64,
10900 /// Flags for this waiter.
10901 flags: FUTEX2_FLAGS,
10902 /// Reserved member to preserve alignment.
10903 __reserved: u32 = 0,
10904};
10905
10906pub const cache_stat_range = extern struct {
10907 off: u64,
10908 len: u64,
10909};
10910
10911pub const cache_stat = extern struct {
10912 /// Number of cached pages.
10913 cache: u64,
10914 /// Number of dirty pages.
10915 dirty: u64,
10916 /// Number of pages marked for writeback.
10917 writeback: u64,
10918 /// Number of pages evicted from the cache.
10919 evicted: u64,
10920 /// Number of recently evicted pages.
10921 /// A page is recently evicted if its last eviction was recent enough that its
10922 /// reentry to the cache would indicate that it is actively being used by the
10923 /// system, and that there is memory pressure on the system.
10924 recently_evicted: u64,
10925};
10926
10927pub const SHADOW_STACK = struct {
10928 /// Set up a restore token in the shadow stack.
10929 pub const SET_TOKEN: u64 = 1 << 0;
10930};
10931
10932pub const msghdr = extern struct {
10933 name: ?*sockaddr,
10934 namelen: socklen_t,
10935 iov: [*]iovec,
10936 /// The kernel and glibc use `usize` for this field; POSIX and musl use `c_int`.
10937 iovlen: usize,
10938 control: ?*anyopaque,
10939 /// The kernel and glibc use `usize` for this field; POSIX and musl use `socklen_t`.
10940 controllen: usize,
10941 flags: u32,
10942};
10943
10944pub const msghdr_const = extern struct {
10945 name: ?*const sockaddr,
10946 namelen: socklen_t,
10947 iov: [*]const iovec_const,
10948 iovlen: usize,
10949 control: ?*const anyopaque,
10950 controllen: usize,
10951 flags: u32,
10952};
10953
10954// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/socket.h?id=b320789d6883cc00ac78ce83bccbfe7ed58afcf0#n105
10955pub const cmsghdr = extern struct {
10956 /// The kernel and glibc use `usize` for this field; musl uses `socklen_t`.
10957 len: usize,
10958 level: i32,
10959 type: i32,
10960};
10961
10962pub const riscv_hwprobe = extern struct {
10963 key: i64,
10964 value: u64,
10965};
10966
10967pub const RISCV_HWPROBE = struct {
10968 pub const KEY = struct {
10969 pub const MVENDORID = 0;
10970 pub const MARCHID = 1;
10971 pub const MIMPID = 2;
10972 pub const BASE_BEHAVIOR = 3;
10973 pub const IMA_EXT_0 = 4;
10974 pub const CPUPERF_0 = 5;
10975 pub const ZICBOZ_BLOCK_SIZE = 6;
10976 pub const HIGHEST_VIRT_ADDRESS = 7;
10977 pub const TIME_CSR_FREQ = 8;
10978 pub const MISALIGNED_SCALAR_PERF = 9;
10979 pub const MISALIGNED_VECTOR_PERF = 10;
10980 pub const VENDOR_EXT_THEAD_0 = 11;
10981 pub const ZICBOM_BLOCK_SIZE = 12;
10982 pub const VENDOR_EXT_SIFIVE_0 = 13;
10983 pub const VENDOR_EXT_MIPS_0 = 14;
10984 pub const ZICBOP_BLOCK_SIZE = 15;
10985 pub const IMA_EXT_1 = 16;
10986 };
10987
10988 pub const FLAGS_WHICH_CPUS = 1 << 0;
10989
10990 pub const BASE_BEHAVIOR_IMA = 1 << 0;
10991
10992 pub const IMA_EXT_0 = struct {
10993 pub const IMA_FD = 1 << 0;
10994 pub const IMA_C = 1 << 1;
10995 pub const IMA_V = 1 << 2;
10996 pub const EXT_ZBA = 1 << 3;
10997 pub const EXT_ZBB = 1 << 4;
10998 pub const EXT_ZBS = 1 << 5;
10999 pub const EXT_ZICBOZ = 1 << 6;
11000 pub const EXT_ZBC = 1 << 7;
11001 pub const EXT_ZBKB = 1 << 8;
11002 pub const EXT_ZBKC = 1 << 9;
11003 pub const EXT_ZBKX = 1 << 10;
11004 pub const EXT_ZKND = 1 << 11;
11005 pub const EXT_ZKNE = 1 << 12;
11006 pub const EXT_ZKNH = 1 << 13;
11007 pub const EXT_ZKSED = 1 << 14;
11008 pub const EXT_ZKSH = 1 << 15;
11009 pub const EXT_ZKT = 1 << 16;
11010 pub const EXT_ZVBB = 1 << 17;
11011 pub const EXT_ZVBC = 1 << 18;
11012 pub const EXT_ZVKB = 1 << 19;
11013 pub const EXT_ZVKG = 1 << 20;
11014 pub const EXT_ZVKNED = 1 << 21;
11015 pub const EXT_ZVKNHA = 1 << 22;
11016 pub const EXT_ZVKNHB = 1 << 23;
11017 pub const EXT_ZVKSED = 1 << 24;
11018 pub const EXT_ZVKSH = 1 << 25;
11019 pub const EXT_ZVKT = 1 << 26;
11020 pub const EXT_ZFH = 1 << 27;
11021 pub const EXT_ZFHMIN = 1 << 28;
11022 pub const EXT_ZIHINTNTL = 1 << 29;
11023 pub const EXT_ZVFH = 1 << 30;
11024 pub const EXT_ZVFHMIN = 1 << 31;
11025 pub const EXT_ZFA = 1 << 32;
11026 pub const EXT_ZTSO = 1 << 33;
11027 pub const EXT_ZACAS = 1 << 34;
11028 pub const EXT_ZICOND = 1 << 35;
11029 pub const EXT_ZIHINTPAUSE = 1 << 36;
11030 pub const EXT_ZVE32X = 1 << 37;
11031 pub const EXT_ZVE32F = 1 << 38;
11032 pub const EXT_ZVE64X = 1 << 39;
11033 pub const EXT_ZVE64F = 1 << 40;
11034 pub const EXT_ZVE64D = 1 << 41;
11035 pub const EXT_ZIMOP = 1 << 42;
11036 pub const EXT_ZCA = 1 << 43;
11037 pub const EXT_ZCB = 1 << 44;
11038 pub const EXT_ZCD = 1 << 45;
11039 pub const EXT_ZCF = 1 << 46;
11040 pub const EXT_ZCMOP = 1 << 47;
11041 pub const EXT_ZAWRS = 1 << 48;
11042 pub const EXT_SUPM = 1 << 49;
11043 pub const EXT_ZICNTR = 1 << 50;
11044 pub const EXT_ZIHPM = 1 << 51;
11045 pub const EXT_ZFBFMIN = 1 << 52;
11046 pub const EXT_ZVFBFMIN = 1 << 53;
11047 pub const EXT_ZVFBFWMA = 1 << 54;
11048 pub const EXT_ZICBOM = 1 << 55;
11049 pub const EXT_ZAAMO = 1 << 56;
11050 pub const EXT_ZALRSC = 1 << 57;
11051 pub const EXT_ZABHA = 1 << 58;
11052 pub const EXT_ZALASR = 1 << 59;
11053 pub const EXT_ZICBOP = 1 << 60;
11054 pub const EXT_ZILSD = 1 << 61;
11055 pub const EXT_ZCLSD = 1 << 62;
11056 pub const EXT_ZICFILP = 1 << 63;
11057 };
11058
11059 pub const IMA_EXT_1_EXT_ZICFISS = 1 << 0;
11060
11061 pub const MISALIGNED_SCALAR = struct {
11062 pub const UNKNOWN = 0;
11063 pub const EMULATED = 1;
11064 pub const SLOW = 2;
11065 pub const FAST = 3;
11066 pub const UNSUPPORTED = 4;
11067 };
11068
11069 pub const MISALIGNED_VECTOR = struct {
11070 pub const UNKNOWN = 0;
11071 pub const SLOW = 2;
11072 pub const FAST = 3;
11073 pub const UNSUPPORTED = 4;
11074 };
11075
11076 pub const MIPS_VENDOR_EXT_XMIPSEXECTL = 1 << 0;
11077
11078 pub const SIFIVE_VENDOR_EXT = struct {
11079 pub const XSFVQMACCDOD = 1 << 0;
11080 pub const XSFVQMACCQOQ = 1 << 1;
11081 pub const XSFVFNRCLIPXFQF = 1 << 2;
11082 pub const XSFVFWMACCQQQ = 1 << 3;
11083 };
11084};