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(&timespec{
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};