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