1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const socklen_t = linux.socklen_t;
5const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
7const uid_t = linux.uid_t;
8const gid_t = linux.gid_t;
9const pid_t = linux.pid_t;
10const timespec = linux.timespec;
11
12pub fn syscall0(number: SYS) usize {
13    return asm volatile (
14        \\ syscall
15        \\ blez $7, 1f
16        \\ subu $2, $0, $2
17        \\ 1:
18        : [ret] "={$2}" (-> usize),
19        : [number] "{$2}" (@enumToInt(number)),
20        : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
21    );
22}
23
24pub fn syscall_pipe(fd: *[2]i32) usize {
25    return asm volatile (
26        \\ .set noat
27        \\ .set noreorder
28        \\ syscall
29        \\ blez $7, 1f
30        \\ nop
31        \\ b 2f
32        \\ subu $2, $0, $2
33        \\ 1:
34        \\ sw $2, 0($4)
35        \\ sw $3, 4($4)
36        \\ 2:
37        : [ret] "={$2}" (-> usize),
38        : [number] "{$2}" (@enumToInt(SYS.pipe)),
39          [fd] "{$4}" (fd),
40        : "$1", "$3", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
41    );
42}
43
44pub fn syscall1(number: SYS, arg1: usize) usize {
45    return asm volatile (
46        \\ syscall
47        \\ blez $7, 1f
48        \\ subu $2, $0, $2
49        \\ 1:
50        : [ret] "={$2}" (-> usize),
51        : [number] "{$2}" (@enumToInt(number)),
52          [arg1] "{$4}" (arg1),
53        : "$1", "$3", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
54    );
55}
56
57pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
58    return asm volatile (
59        \\ syscall
60        \\ blez $7, 1f
61        \\ subu $2, $0, $2
62        \\ 1:
63        : [ret] "={$2}" (-> usize),
64        : [number] "{$2}" (@enumToInt(number)),
65          [arg1] "{$4}" (arg1),
66          [arg2] "{$5}" (arg2),
67        : "$1", "$3", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
68    );
69}
70
71pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
72    return asm volatile (
73        \\ syscall
74        \\ blez $7, 1f
75        \\ subu $2, $0, $2
76        \\ 1:
77        : [ret] "={$2}" (-> usize),
78        : [number] "{$2}" (@enumToInt(number)),
79          [arg1] "{$4}" (arg1),
80          [arg2] "{$5}" (arg2),
81          [arg3] "{$6}" (arg3),
82        : "$1", "$3", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
83    );
84}
85
86pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
87    return asm volatile (
88        \\ syscall
89        \\ blez $7, 1f
90        \\ subu $2, $0, $2
91        \\ 1:
92        : [ret] "={$2}" (-> usize),
93        : [number] "{$2}" (@enumToInt(number)),
94          [arg1] "{$4}" (arg1),
95          [arg2] "{$5}" (arg2),
96          [arg3] "{$6}" (arg3),
97          [arg4] "{$7}" (arg4),
98        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
99    );
100}
101
102pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
103    return asm volatile (
104        \\ .set noat
105        \\ subu $sp, $sp, 24
106        \\ sw %[arg5], 16($sp)
107        \\ syscall
108        \\ addu $sp, $sp, 24
109        \\ blez $7, 1f
110        \\ subu $2, $0, $2
111        \\ 1:
112        : [ret] "={$2}" (-> usize),
113        : [number] "{$2}" (@enumToInt(number)),
114          [arg1] "{$4}" (arg1),
115          [arg2] "{$5}" (arg2),
116          [arg3] "{$6}" (arg3),
117          [arg4] "{$7}" (arg4),
118          [arg5] "r" (arg5),
119        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
120    );
121}
122
123// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
124// the first four arguments even though they're passed in $a0-$a3.
125
126pub fn syscall6(
127    number: SYS,
128    arg1: usize,
129    arg2: usize,
130    arg3: usize,
131    arg4: usize,
132    arg5: usize,
133    arg6: usize,
134) usize {
135    return asm volatile (
136        \\ .set noat
137        \\ subu $sp, $sp, 24
138        \\ sw %[arg5], 16($sp)
139        \\ sw %[arg6], 20($sp)
140        \\ syscall
141        \\ addu $sp, $sp, 24
142        \\ blez $7, 1f
143        \\ subu $2, $0, $2
144        \\ 1:
145        : [ret] "={$2}" (-> usize),
146        : [number] "{$2}" (@enumToInt(number)),
147          [arg1] "{$4}" (arg1),
148          [arg2] "{$5}" (arg2),
149          [arg3] "{$6}" (arg3),
150          [arg4] "{$7}" (arg4),
151          [arg5] "r" (arg5),
152          [arg6] "r" (arg6),
153        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
154    );
155}
156
157pub fn syscall7(
158    number: SYS,
159    arg1: usize,
160    arg2: usize,
161    arg3: usize,
162    arg4: usize,
163    arg5: usize,
164    arg6: usize,
165    arg7: usize,
166) usize {
167    return asm volatile (
168        \\ .set noat
169        \\ subu $sp, $sp, 32
170        \\ sw %[arg5], 16($sp)
171        \\ sw %[arg6], 20($sp)
172        \\ sw %[arg7], 24($sp)
173        \\ syscall
174        \\ addu $sp, $sp, 32
175        \\ blez $7, 1f
176        \\ subu $2, $0, $2
177        \\ 1:
178        : [ret] "={$2}" (-> usize),
179        : [number] "{$2}" (@enumToInt(number)),
180          [arg1] "{$4}" (arg1),
181          [arg2] "{$5}" (arg2),
182          [arg3] "{$6}" (arg3),
183          [arg4] "{$7}" (arg4),
184          [arg5] "r" (arg5),
185          [arg6] "r" (arg6),
186          [arg7] "r" (arg7),
187        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
188    );
189}
190
191/// This matches the libc clone function.
192pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
193
194pub fn restore() callconv(.Naked) void {
195    return asm volatile ("syscall"
196        :
197        : [number] "{$2}" (@enumToInt(SYS.sigreturn)),
198        : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
199    );
200}
201
202pub fn restore_rt() callconv(.Naked) void {
203    return asm volatile ("syscall"
204        :
205        : [number] "{$2}" (@enumToInt(SYS.rt_sigreturn)),
206        : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
207    );
208}
209
210pub const SYS = enum(usize) {
211    pub const Linux = 4000;
212
213    syscall = Linux + 0,
214    exit = Linux + 1,
215    fork = Linux + 2,
216    read = Linux + 3,
217    write = Linux + 4,
218    open = Linux + 5,
219    close = Linux + 6,
220    waitpid = Linux + 7,
221    creat = Linux + 8,
222    link = Linux + 9,
223    unlink = Linux + 10,
224    execve = Linux + 11,
225    chdir = Linux + 12,
226    time = Linux + 13,
227    mknod = Linux + 14,
228    chmod = Linux + 15,
229    lchown = Linux + 16,
230    @"break" = Linux + 17,
231    unused18 = Linux + 18,
232    lseek = Linux + 19,
233    getpid = Linux + 20,
234    mount = Linux + 21,
235    umount = Linux + 22,
236    setuid = Linux + 23,
237    getuid = Linux + 24,
238    stime = Linux + 25,
239    ptrace = Linux + 26,
240    alarm = Linux + 27,
241    unused28 = Linux + 28,
242    pause = Linux + 29,
243    utime = Linux + 30,
244    stty = Linux + 31,
245    gtty = Linux + 32,
246    access = Linux + 33,
247    nice = Linux + 34,
248    ftime = Linux + 35,
249    sync = Linux + 36,
250    kill = Linux + 37,
251    rename = Linux + 38,
252    mkdir = Linux + 39,
253    rmdir = Linux + 40,
254    dup = Linux + 41,
255    pipe = Linux + 42,
256    times = Linux + 43,
257    prof = Linux + 44,
258    brk = Linux + 45,
259    setgid = Linux + 46,
260    getgid = Linux + 47,
261    signal = Linux + 48,
262    geteuid = Linux + 49,
263    getegid = Linux + 50,
264    acct = Linux + 51,
265    umount2 = Linux + 52,
266    lock = Linux + 53,
267    ioctl = Linux + 54,
268    fcntl = Linux + 55,
269    mpx = Linux + 56,
270    setpgid = Linux + 57,
271    ulimit = Linux + 58,
272    unused59 = Linux + 59,
273    umask = Linux + 60,
274    chroot = Linux + 61,
275    ustat = Linux + 62,
276    dup2 = Linux + 63,
277    getppid = Linux + 64,
278    getpgrp = Linux + 65,
279    setsid = Linux + 66,
280    sigaction = Linux + 67,
281    sgetmask = Linux + 68,
282    ssetmask = Linux + 69,
283    setreuid = Linux + 70,
284    setregid = Linux + 71,
285    sigsuspend = Linux + 72,
286    sigpending = Linux + 73,
287    sethostname = Linux + 74,
288    setrlimit = Linux + 75,
289    getrlimit = Linux + 76,
290    getrusage = Linux + 77,
291    gettimeofday = Linux + 78,
292    settimeofday = Linux + 79,
293    getgroups = Linux + 80,
294    setgroups = Linux + 81,
295    reserved82 = Linux + 82,
296    symlink = Linux + 83,
297    unused84 = Linux + 84,
298    readlink = Linux + 85,
299    uselib = Linux + 86,
300    swapon = Linux + 87,
301    reboot = Linux + 88,
302    readdir = Linux + 89,
303    mmap = Linux + 90,
304    munmap = Linux + 91,
305    truncate = Linux + 92,
306    ftruncate = Linux + 93,
307    fchmod = Linux + 94,
308    fchown = Linux + 95,
309    getpriority = Linux + 96,
310    setpriority = Linux + 97,
311    profil = Linux + 98,
312    statfs = Linux + 99,
313    fstatfs = Linux + 100,
314    ioperm = Linux + 101,
315    socketcall = Linux + 102,
316    syslog = Linux + 103,
317    setitimer = Linux + 104,
318    getitimer = Linux + 105,
319    stat = Linux + 106,
320    lstat = Linux + 107,
321    fstat = Linux + 108,
322    unused109 = Linux + 109,
323    iopl = Linux + 110,
324    vhangup = Linux + 111,
325    idle = Linux + 112,
326    vm86 = Linux + 113,
327    wait4 = Linux + 114,
328    swapoff = Linux + 115,
329    sysinfo = Linux + 116,
330    ipc = Linux + 117,
331    fsync = Linux + 118,
332    sigreturn = Linux + 119,
333    clone = Linux + 120,
334    setdomainname = Linux + 121,
335    uname = Linux + 122,
336    modify_ldt = Linux + 123,
337    adjtimex = Linux + 124,
338    mprotect = Linux + 125,
339    sigprocmask = Linux + 126,
340    create_module = Linux + 127,
341    init_module = Linux + 128,
342    delete_module = Linux + 129,
343    get_kernel_syms = Linux + 130,
344    quotactl = Linux + 131,
345    getpgid = Linux + 132,
346    fchdir = Linux + 133,
347    bdflush = Linux + 134,
348    sysfs = Linux + 135,
349    personality = Linux + 136,
350    afs_syscall = Linux + 137,
351    setfsuid = Linux + 138,
352    setfsgid = Linux + 139,
353    _llseek = Linux + 140,
354    getdents = Linux + 141,
355    _newselect = Linux + 142,
356    flock = Linux + 143,
357    msync = Linux + 144,
358    readv = Linux + 145,
359    writev = Linux + 146,
360    cacheflush = Linux + 147,
361    cachectl = Linux + 148,
362    sysmips = Linux + 149,
363    unused150 = Linux + 150,
364    getsid = Linux + 151,
365    fdatasync = Linux + 152,
366    _sysctl = Linux + 153,
367    mlock = Linux + 154,
368    munlock = Linux + 155,
369    mlockall = Linux + 156,
370    munlockall = Linux + 157,
371    sched_setparam = Linux + 158,
372    sched_getparam = Linux + 159,
373    sched_setscheduler = Linux + 160,
374    sched_getscheduler = Linux + 161,
375    sched_yield = Linux + 162,
376    sched_get_priority_max = Linux + 163,
377    sched_get_priority_min = Linux + 164,
378    sched_rr_get_interval = Linux + 165,
379    nanosleep = Linux + 166,
380    mremap = Linux + 167,
381    accept = Linux + 168,
382    bind = Linux + 169,
383    connect = Linux + 170,
384    getpeername = Linux + 171,
385    getsockname = Linux + 172,
386    getsockopt = Linux + 173,
387    listen = Linux + 174,
388    recv = Linux + 175,
389    recvfrom = Linux + 176,
390    recvmsg = Linux + 177,
391    send = Linux + 178,
392    sendmsg = Linux + 179,
393    sendto = Linux + 180,
394    setsockopt = Linux + 181,
395    shutdown = Linux + 182,
396    socket = Linux + 183,
397    socketpair = Linux + 184,
398    setresuid = Linux + 185,
399    getresuid = Linux + 186,
400    query_module = Linux + 187,
401    poll = Linux + 188,
402    nfsservctl = Linux + 189,
403    setresgid = Linux + 190,
404    getresgid = Linux + 191,
405    prctl = Linux + 192,
406    rt_sigreturn = Linux + 193,
407    rt_sigaction = Linux + 194,
408    rt_sigprocmask = Linux + 195,
409    rt_sigpending = Linux + 196,
410    rt_sigtimedwait = Linux + 197,
411    rt_sigqueueinfo = Linux + 198,
412    rt_sigsuspend = Linux + 199,
413    pread64 = Linux + 200,
414    pwrite64 = Linux + 201,
415    chown = Linux + 202,
416    getcwd = Linux + 203,
417    capget = Linux + 204,
418    capset = Linux + 205,
419    sigaltstack = Linux + 206,
420    sendfile = Linux + 207,
421    getpmsg = Linux + 208,
422    putpmsg = Linux + 209,
423    mmap2 = Linux + 210,
424    truncate64 = Linux + 211,
425    ftruncate64 = Linux + 212,
426    stat64 = Linux + 213,
427    lstat64 = Linux + 214,
428    fstat64 = Linux + 215,
429    pivot_root = Linux + 216,
430    mincore = Linux + 217,
431    madvise = Linux + 218,
432    getdents64 = Linux + 219,
433    fcntl64 = Linux + 220,
434    reserved221 = Linux + 221,
435    gettid = Linux + 222,
436    readahead = Linux + 223,
437    setxattr = Linux + 224,
438    lsetxattr = Linux + 225,
439    fsetxattr = Linux + 226,
440    getxattr = Linux + 227,
441    lgetxattr = Linux + 228,
442    fgetxattr = Linux + 229,
443    listxattr = Linux + 230,
444    llistxattr = Linux + 231,
445    flistxattr = Linux + 232,
446    removexattr = Linux + 233,
447    lremovexattr = Linux + 234,
448    fremovexattr = Linux + 235,
449    tkill = Linux + 236,
450    sendfile64 = Linux + 237,
451    futex = Linux + 238,
452    sched_setaffinity = Linux + 239,
453    sched_getaffinity = Linux + 240,
454    io_setup = Linux + 241,
455    io_destroy = Linux + 242,
456    io_getevents = Linux + 243,
457    io_submit = Linux + 244,
458    io_cancel = Linux + 245,
459    exit_group = Linux + 246,
460    lookup_dcookie = Linux + 247,
461    epoll_create = Linux + 248,
462    epoll_ctl = Linux + 249,
463    epoll_wait = Linux + 250,
464    remap_file_pages = Linux + 251,
465    set_tid_address = Linux + 252,
466    restart_syscall = Linux + 253,
467    fadvise64 = Linux + 254,
468    statfs64 = Linux + 255,
469    fstatfs64 = Linux + 256,
470    timer_create = Linux + 257,
471    timer_settime = Linux + 258,
472    timer_gettime = Linux + 259,
473    timer_getoverrun = Linux + 260,
474    timer_delete = Linux + 261,
475    clock_settime = Linux + 262,
476    clock_gettime = Linux + 263,
477    clock_getres = Linux + 264,
478    clock_nanosleep = Linux + 265,
479    tgkill = Linux + 266,
480    utimes = Linux + 267,
481    mbind = Linux + 268,
482    get_mempolicy = Linux + 269,
483    set_mempolicy = Linux + 270,
484    mq_open = Linux + 271,
485    mq_unlink = Linux + 272,
486    mq_timedsend = Linux + 273,
487    mq_timedreceive = Linux + 274,
488    mq_notify = Linux + 275,
489    mq_getsetattr = Linux + 276,
490    vserver = Linux + 277,
491    waitid = Linux + 278,
492    add_key = Linux + 280,
493    request_key = Linux + 281,
494    keyctl = Linux + 282,
495    set_thread_area = Linux + 283,
496    inotify_init = Linux + 284,
497    inotify_add_watch = Linux + 285,
498    inotify_rm_watch = Linux + 286,
499    migrate_pages = Linux + 287,
500    openat = Linux + 288,
501    mkdirat = Linux + 289,
502    mknodat = Linux + 290,
503    fchownat = Linux + 291,
504    futimesat = Linux + 292,
505    fstatat64 = Linux + 293,
506    unlinkat = Linux + 294,
507    renameat = Linux + 295,
508    linkat = Linux + 296,
509    symlinkat = Linux + 297,
510    readlinkat = Linux + 298,
511    fchmodat = Linux + 299,
512    faccessat = Linux + 300,
513    pselect6 = Linux + 301,
514    ppoll = Linux + 302,
515    unshare = Linux + 303,
516    splice = Linux + 304,
517    sync_file_range = Linux + 305,
518    tee = Linux + 306,
519    vmsplice = Linux + 307,
520    move_pages = Linux + 308,
521    set_robust_list = Linux + 309,
522    get_robust_list = Linux + 310,
523    kexec_load = Linux + 311,
524    getcpu = Linux + 312,
525    epoll_pwait = Linux + 313,
526    ioprio_set = Linux + 314,
527    ioprio_get = Linux + 315,
528    utimensat = Linux + 316,
529    signalfd = Linux + 317,
530    timerfd = Linux + 318,
531    eventfd = Linux + 319,
532    fallocate = Linux + 320,
533    timerfd_create = Linux + 321,
534    timerfd_gettime = Linux + 322,
535    timerfd_settime = Linux + 323,
536    signalfd4 = Linux + 324,
537    eventfd2 = Linux + 325,
538    epoll_create1 = Linux + 326,
539    dup3 = Linux + 327,
540    pipe2 = Linux + 328,
541    inotify_init1 = Linux + 329,
542    preadv = Linux + 330,
543    pwritev = Linux + 331,
544    rt_tgsigqueueinfo = Linux + 332,
545    perf_event_open = Linux + 333,
546    accept4 = Linux + 334,
547    recvmmsg = Linux + 335,
548    fanotify_init = Linux + 336,
549    fanotify_mark = Linux + 337,
550    prlimit64 = Linux + 338,
551    name_to_handle_at = Linux + 339,
552    open_by_handle_at = Linux + 340,
553    clock_adjtime = Linux + 341,
554    syncfs = Linux + 342,
555    sendmmsg = Linux + 343,
556    setns = Linux + 344,
557    process_vm_readv = Linux + 345,
558    process_vm_writev = Linux + 346,
559    kcmp = Linux + 347,
560    finit_module = Linux + 348,
561    sched_setattr = Linux + 349,
562    sched_getattr = Linux + 350,
563    renameat2 = Linux + 351,
564    seccomp = Linux + 352,
565    getrandom = Linux + 353,
566    memfd_create = Linux + 354,
567    bpf = Linux + 355,
568    execveat = Linux + 356,
569    userfaultfd = Linux + 357,
570    membarrier = Linux + 358,
571    mlock2 = Linux + 359,
572    copy_file_range = Linux + 360,
573    preadv2 = Linux + 361,
574    pwritev2 = Linux + 362,
575    pkey_mprotect = Linux + 363,
576    pkey_alloc = Linux + 364,
577    pkey_free = Linux + 365,
578    statx = Linux + 366,
579    rseq = Linux + 367,
580    io_pgetevents = Linux + 368,
581    semget = Linux + 393,
582    semctl = Linux + 394,
583    shmget = Linux + 395,
584    shmctl = Linux + 396,
585    shmat = Linux + 397,
586    shmdt = Linux + 398,
587    msgget = Linux + 399,
588    msgsnd = Linux + 400,
589    msgrcv = Linux + 401,
590    msgctl = Linux + 402,
591    clock_gettime64 = Linux + 403,
592    clock_settime64 = Linux + 404,
593    clock_adjtime64 = Linux + 405,
594    clock_getres_time64 = Linux + 406,
595    clock_nanosleep_time64 = Linux + 407,
596    timer_gettime64 = Linux + 408,
597    timer_settime64 = Linux + 409,
598    timerfd_gettime64 = Linux + 410,
599    timerfd_settime64 = Linux + 411,
600    utimensat_time64 = Linux + 412,
601    pselect6_time64 = Linux + 413,
602    ppoll_time64 = Linux + 414,
603    io_pgetevents_time64 = Linux + 416,
604    recvmmsg_time64 = Linux + 417,
605    mq_timedsend_time64 = Linux + 418,
606    mq_timedreceive_time64 = Linux + 419,
607    semtimedop_time64 = Linux + 420,
608    rt_sigtimedwait_time64 = Linux + 421,
609    futex_time64 = Linux + 422,
610    sched_rr_get_interval_time64 = Linux + 423,
611    pidfd_send_signal = Linux + 424,
612    io_uring_setup = Linux + 425,
613    io_uring_enter = Linux + 426,
614    io_uring_register = Linux + 427,
615    open_tree = Linux + 428,
616    move_mount = Linux + 429,
617    fsopen = Linux + 430,
618    fsconfig = Linux + 431,
619    fsmount = Linux + 432,
620    fspick = Linux + 433,
621    pidfd_open = Linux + 434,
622    clone3 = Linux + 435,
623    close_range = Linux + 436,
624    openat2 = Linux + 437,
625    pidfd_getfd = Linux + 438,
626    faccessat2 = Linux + 439,
627    process_madvise = Linux + 440,
628    epoll_pwait2 = Linux + 441,
629    mount_setattr = Linux + 442,
630    landlock_create_ruleset = Linux + 444,
631    landlock_add_rule = Linux + 445,
632    landlock_restrict_self = Linux + 446,
633
634    _,
635};
636
637pub const O = struct {
638    pub const CREAT = 0o0400;
639    pub const EXCL = 0o02000;
640    pub const NOCTTY = 0o04000;
641    pub const TRUNC = 0o01000;
642    pub const APPEND = 0o0010;
643    pub const NONBLOCK = 0o0200;
644    pub const DSYNC = 0o0020;
645    pub const SYNC = 0o040020;
646    pub const RSYNC = 0o040020;
647    pub const DIRECTORY = 0o0200000;
648    pub const NOFOLLOW = 0o0400000;
649    pub const CLOEXEC = 0o02000000;
650
651    pub const ASYNC = 0o010000;
652    pub const DIRECT = 0o0100000;
653    pub const LARGEFILE = 0o020000;
654    pub const NOATIME = 0o01000000;
655    pub const PATH = 0o010000000;
656    pub const TMPFILE = 0o020200000;
657    pub const NDELAY = NONBLOCK;
658};
659
660pub const F = struct {
661    pub const DUPFD = 0;
662    pub const GETFD = 1;
663    pub const SETFD = 2;
664    pub const GETFL = 3;
665    pub const SETFL = 4;
666
667    pub const SETOWN = 24;
668    pub const GETOWN = 23;
669    pub const SETSIG = 10;
670    pub const GETSIG = 11;
671
672    pub const GETLK = 33;
673    pub const SETLK = 34;
674    pub const SETLKW = 35;
675
676    pub const RDLCK = 0;
677    pub const WRLCK = 1;
678    pub const UNLCK = 2;
679
680    pub const SETOWN_EX = 15;
681    pub const GETOWN_EX = 16;
682
683    pub const GETOWNER_UIDS = 17;
684};
685
686pub const LOCK = struct {
687    pub const SH = 1;
688    pub const EX = 2;
689    pub const UN = 8;
690    pub const NB = 4;
691};
692
693pub const MMAP2_UNIT = 4096;
694
695pub const MAP = struct {
696    pub const NORESERVE = 0x0400;
697    pub const GROWSDOWN = 0x1000;
698    pub const DENYWRITE = 0x2000;
699    pub const EXECUTABLE = 0x4000;
700    pub const LOCKED = 0x8000;
701    pub const @"32BIT" = 0x40;
702};
703
704pub const VDSO = struct {
705    pub const CGT_SYM = "__kernel_clock_gettime";
706    pub const CGT_VER = "LINUX_2.6.39";
707};
708
709pub const Flock = extern struct {
710    l_type: i16,
711    l_whence: i16,
712    __pad0: [4]u8,
713    l_start: off_t,
714    l_len: off_t,
715    l_pid: pid_t,
716    __unused: [4]u8,
717};
718
719pub const blksize_t = i32;
720pub const nlink_t = u32;
721pub const time_t = i32;
722pub const mode_t = u32;
723pub const off_t = i64;
724pub const ino_t = u64;
725pub const dev_t = u64;
726pub const blkcnt_t = i64;
727
728// The `stat` definition used by the Linux kernel.
729pub const Stat = extern struct {
730    dev: u32,
731    __pad0: [3]u32, // Reserved for st_dev expansion
732    ino: ino_t,
733    mode: mode_t,
734    nlink: nlink_t,
735    uid: uid_t,
736    gid: gid_t,
737    rdev: u32,
738    __pad1: [3]u32,
739    size: off_t,
740    atim: timespec,
741    mtim: timespec,
742    ctim: timespec,
743    blksize: blksize_t,
744    __pad3: u32,
745    blocks: blkcnt_t,
746    __pad4: [14]usize,
747
748    pub fn atime(self: @This()) timespec {
749        return self.atim;
750    }
751
752    pub fn mtime(self: @This()) timespec {
753        return self.mtim;
754    }
755
756    pub fn ctime(self: @This()) timespec {
757        return self.ctim;
758    }
759};
760
761pub const timeval = extern struct {
762    tv_sec: isize,
763    tv_usec: isize,
764};
765
766pub const timezone = extern struct {
767    tz_minuteswest: i32,
768    tz_dsttime: i32,
769};
770
771pub const Elf_Symndx = u32;
772
773pub const rlimit_resource = enum(c_int) {
774    /// Per-process CPU limit, in seconds.
775    CPU,
776
777    /// Largest file that can be created, in bytes.
778    FSIZE,
779
780    /// Maximum size of data segment, in bytes.
781    DATA,
782
783    /// Maximum size of stack segment, in bytes.
784    STACK,
785
786    /// Largest core file that can be created, in bytes.
787    CORE,
788
789    /// Number of open files.
790    NOFILE,
791
792    /// Address space limit.
793    AS,
794
795    /// Largest resident set size, in bytes.
796    /// This affects swapping; processes that are exceeding their
797    /// resident set size will be more likely to have physical memory
798    /// taken from them.
799    RSS,
800
801    /// Number of processes.
802    NPROC,
803
804    /// Locked-in-memory address space.
805    MEMLOCK,
806
807    /// Maximum number of file locks.
808    LOCKS,
809
810    /// Maximum number of pending signals.
811    SIGPENDING,
812
813    /// Maximum bytes in POSIX message queues.
814    MSGQUEUE,
815
816    /// Maximum nice priority allowed to raise to.
817    /// Nice levels 19 .. -20 correspond to 0 .. 39
818    /// values of this resource limit.
819    NICE,
820
821    /// Maximum realtime priority allowed for non-priviledged
822    /// processes.
823    RTPRIO,
824
825    /// Maximum CPU time in µs that a process scheduled under a real-time
826    /// scheduling policy may consume without making a blocking system
827    /// call before being forcibly descheduled.
828    RTTIME,
829
830    _,
831};
832