syscalls.ha (27958B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 let pathbuf: [PATH_MAX]u8 = [0...]; 5 6 // For functions that need more than one path, i.e. unveil, linkat, renameat, etc. 7 let pathbuf1: [PATH_MAX]u8 = [0...]; 8 9 export type path = (str | []u8 | *const u8); 10 11 fn copy_cpath(path: path, buf: []u8) (*const u8 | errno) = { 12 let path = match (path) { 13 case let c: *const u8 => 14 return c; 15 case let s: str => 16 let ptr = &s: *struct { 17 buf: *[*]u8, 18 length: size, 19 capacity: size, 20 }; 21 yield ptr.buf[..ptr.length]; 22 case let b: []u8 => 23 yield b; 24 }; 25 if (len(path) + 1 >= len(buf)) { 26 return ENAMETOOLONG; 27 }; 28 memcpy(buf: *[*]u8, path: *[*]u8, len(path)); 29 buf[len(path)] = 0; 30 return buf: *[*]u8: *const u8; 31 }; 32 33 // NUL terminates a string and stores it in a static buffer of PATH_MAX bytes in 34 // length. 35 fn cpath(path: path) (*const u8 | errno) = { 36 return copy_cpath(path, pathbuf); 37 }; 38 39 // /usr/include/errno.h: #define errno (*__errno()) 40 @symbol("__errno") fn __errno() *int; 41 42 // exit 43 export @symbol("exit") fn exit(status: int) never; 44 45 // fork 46 47 @symbol("fork") fn libc_fork() int; 48 49 export fn fork() (int | void | errno) = { 50 let res = libc_fork(); 51 if (res == -1) { 52 return *__errno(): errno; 53 }; 54 if (res == 0) { 55 return; 56 }; 57 return res; 58 }; 59 60 // read 61 62 @symbol("read") fn libc_read(d: int, buf: *opaque, nbytes: size) size; 63 64 export fn read(fd: int, buf: *opaque, count: size) (size | errno) = { 65 let res: u64 = libc_read(fd, buf, count); 66 if (res == -1) { 67 return *__errno(): errno; 68 }; 69 return res; 70 }; 71 72 // write 73 74 @symbol("write") fn libc_write(d: int, buf: *const opaque, nbytes: size) size; 75 76 export fn write(fd: int, buf: *const opaque, count: size) (size | errno) = { 77 let res: u64 = libc_write(fd, buf, count); 78 if (res == -1) { 79 return *__errno(): errno; 80 }; 81 return res; 82 }; 83 84 // open 85 86 @symbol("open") fn libc_open(path: *opaque, flags: int, mode: int) int; 87 88 export fn open(path: path, flags: int, mode: int) (int | errno) = { 89 let res = libc_open(cpath(path)?, flags, mode); 90 if (res == -1) { 91 return *__errno(): errno; 92 }; 93 return res; 94 }; 95 96 // posix_openpt (libc function not a syscall) 97 98 @symbol("posix_openpt") fn libc_openpt(oflag: int) int; 99 100 export fn posix_openpt(flags: int) (int | errno) = { 101 let res = libc_openpt(flags); 102 if (res == -1) { 103 return *__errno(): errno; 104 }; 105 return res; 106 }; 107 108 // close 109 110 @symbol("close") fn libc_close(d: int) int; 111 112 export fn close(fd: int) (void | errno) = { 113 let res = libc_close(fd); 114 if (res == -1) { 115 return *__errno(): errno; 116 }; 117 }; 118 119 // getentropy 120 // __tfork 121 // link 122 // unlink 123 // wait4 124 125 @symbol("wait4") fn libc_wait4( 126 wpid: pid_t, 127 status: nullable *int, 128 options: int, 129 rusage: nullable *rusage 130 ) pid_t; 131 132 export fn wait4( 133 pid: pid_t, 134 wstatus: nullable *int, 135 options: int, 136 rusage: nullable *rusage, 137 ) (pid_t | errno) = { 138 let res = libc_wait4(pid, wstatus, options, rusage); 139 if (res == -1) { 140 return *__errno(): errno; 141 }; 142 return res; 143 }; 144 145 // chdir 146 147 @symbol("chdir") fn libc_chdir(path: *const u8) int; 148 149 export fn chdir(path: path) (void | errno) = { 150 let res = libc_chdir(cpath(path)?); 151 152 if (res == -1) { 153 return *__errno(): errno; 154 }; 155 }; 156 157 // fchdir 158 159 @symbol("fchdir") fn libc_fchdir(fd: int) int; 160 161 export fn fchdir(fd: int) (void | errno) = { 162 let res = libc_fchdir(fd); 163 164 if (res == -1) { 165 return *__errno(): errno; 166 }; 167 }; 168 169 // mknod 170 // chmod 171 // chown 172 // obreak 173 // getdtablecount 174 // getrusage 175 // getpid 176 177 export @symbol("getpid") fn getpid() pid_t; 178 179 // mount 180 // unmount 181 // setuid 182 183 @symbol("setuid") fn libc_setuid(uid: uid_t) int; 184 185 export fn setuid(uid: uid_t) (void | errno) = { 186 let res = libc_setuid(uid); 187 if (res == -1) { 188 return *__errno(): errno; 189 }; 190 }; 191 192 // getuid 193 194 export @symbol("getuid") fn getuid() uid_t; 195 196 // geteuid 197 198 export @symbol("geteuid") fn geteuid() uid_t; 199 200 // ptrace 201 // recvmsg 202 203 @symbol("recvmsg") fn libc_recvmsg(s: int, msg: *const msghdr, flags: int) i64; 204 205 export fn recvmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { 206 let res = libc_recvmsg(fd, msg, flags); 207 if (res == -1) { 208 return *__errno(): errno; 209 }; 210 // TODO: could overflow 211 return res: int; 212 }; 213 214 // sendmsg 215 216 @symbol("sendmsg") fn libc_sendmsg(s: int, msg: *const msghdr, flags: int) i64; 217 218 export fn sendmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { 219 let res = libc_sendmsg(fd, msg, flags); 220 if (res == -1) { 221 return *__errno(): errno; 222 }; 223 // TODO: could overflow 224 return res: int; 225 }; 226 227 // recvfrom 228 229 @symbol("recvfrom") fn libc_recvfrom( 230 s: int, 231 buf: *opaque, 232 length: size, 233 flags: int, 234 from: nullable *sockaddr, 235 fromlen: nullable *u32, 236 ) i64; 237 238 export fn recvfrom( 239 sockfd: int, 240 buf: *opaque, 241 length: size, 242 flags: int, 243 from: nullable *sockaddr, 244 fromlen: nullable *u32 245 ) (size | errno) = { 246 let res = libc_recvfrom(sockfd, buf, length, flags, from, fromlen); 247 if (res == -1) { 248 return *__errno(): errno; 249 }; 250 return res: size; 251 }; 252 253 // accept 254 // getpeername 255 256 @symbol("getpeername") fn libc_getpeername( 257 s: int, 258 name: *sockaddr, 259 namelen: *u32 260 ) int; 261 262 export fn getpeername( 263 sockfd: int, 264 addr: *sockaddr, 265 addrlen: *u32 266 ) (void | errno) = { 267 let res = libc_getpeername(sockfd, addr, addrlen); 268 if (res == -1) { 269 return *__errno(): errno; 270 }; 271 }; 272 273 // getsockname 274 275 @symbol("getsockname") fn libc_getsockname( 276 sockfd: int, 277 addr: nullable *sockaddr, 278 addrlen: nullable *u32 279 ) int; 280 281 export fn getsockname( 282 sockfd: int, 283 addr: nullable *sockaddr, 284 addrlen: nullable *u32 285 ) (void | errno) = { 286 let res = libc_getsockname(sockfd, addr, addrlen); 287 if (res == -1) { 288 return *__errno(): errno; 289 }; 290 291 }; 292 // access 293 294 @symbol("access") fn libc_access(path: *const u8, amode: int) int; 295 296 export fn access(path: path, amode: int) (bool | errno) = { 297 let res = libc_access(cpath(path)?, amode); 298 if (res == -1) { 299 let err = *__errno(): errno; 300 301 switch (res) { 302 case EACCES => 303 return false; 304 case => 305 return err; 306 }; 307 }; 308 309 return true; 310 }; 311 312 313 // chflags 314 // fchflags 315 // sync 316 // msyscall 317 // stat 318 319 // getppid 320 321 export @symbol("getppid") fn getppid() pid_t; 322 323 // lstat 324 // dup 325 // fstatat 326 327 @symbol("fstatat") fn libc_fstatat(fd: int, path: *const u8, sb: *stat, flag: int) int; 328 329 export fn fstatat( 330 dirfd: int, 331 path: path, 332 stat: *stat, 333 flag: int 334 ) (void | errno) = { 335 let res = libc_fstatat(dirfd, cpath(path)?, stat, flag); 336 if (res == -1) { 337 return *__errno(): errno; 338 }; 339 }; 340 341 342 // getegid 343 344 export @symbol("getegid") fn getegid() gid_t; 345 346 // profil 347 // ktrace 348 // sigaction 349 // sigaltstack 350 351 export @symbol("sigaction") fn libc_sigaction( 352 sig: int, 353 act: *const sigact, 354 oact: nullable *sigact 355 ) int; 356 357 export fn sigaction( 358 signum: int, 359 act: *const sigact, 360 old: nullable *sigact, 361 ) (void | errno) = { 362 let res = libc_sigaction(signum, act, old); 363 if (res == -1) { 364 return *__errno(): errno; 365 }; 366 }; 367 368 export @symbol("sigaltstack") fn libc_sigaltstack( 369 ss: const nullable *stack_t, oss: nullable *stack_t, 370 ) int; 371 372 export fn sigaltstack( 373 ss: const nullable *stack_t, 374 oss: nullable *stack_t, 375 ) (void | errno) = { 376 let res = libc_sigaltstack(ss, oss); 377 if (res == -1) { 378 return *__errno(): errno; 379 }; 380 }; 381 // getgid 382 383 export @symbol("getgid") fn getgid() gid_t; 384 385 // sigprocmask 386 387 @symbol("sigprocmask") fn libc_sigprocmask( 388 how: int, 389 set: nullable *const sigset, 390 old: nullable *sigset 391 ) int; 392 393 export fn sigprocmask( 394 how: int, 395 set: nullable *const sigset, 396 old: nullable *sigset 397 ) (void | errno) = { 398 let res = libc_sigprocmask(how, set, old); 399 if (res == -1) { 400 return *__errno(): errno; 401 }; 402 }; 403 404 // mmap 405 406 @symbol("mmap") fn libc_mmap( 407 addr: nullable *opaque, 408 len_: size, 409 prot: int, 410 flags: int, 411 fd: int, 412 pos: i64 413 ) nullable *opaque; 414 415 export fn mmap( 416 addr: nullable *opaque, 417 len_: size, 418 prot: int, 419 flags: int, 420 fd: int, 421 pos: i64 422 ) (*opaque | errno) = { 423 let res = libc_mmap(addr, len_, prot, flags, fd, pos); 424 425 if (res == null) { 426 return *__errno(): errno; 427 }; 428 return res: *opaque; 429 }; 430 431 // setlogin 432 // acct 433 // sigpending 434 // fstat 435 // ioctl 436 437 @symbol("ioctl") fn libc_ioctl(fd: int, req: u64, arg: u64) int; 438 439 export type ioctl_arg = (nullable *opaque | u64); 440 441 export fn ioctl(fd: int, req: u64, arg: ioctl_arg) (int | errno) = { 442 let res = match (arg) { 443 case let u: u64 => 444 yield libc_ioctl(fd, req, u); 445 case let ptr: nullable *opaque => 446 yield libc_ioctl(fd, req, ptr: uintptr: u64); 447 }; 448 if (res == -1) { 449 return *__errno(): errno; 450 }; 451 return res; 452 }; 453 454 // reboot 455 // revoke 456 // symlink 457 // readlink 458 // execve 459 460 @symbol("execve") fn libc_execve(path: *const u8, argv: *[*]nullable *const u8, 461 envp: *[*]nullable *const u8) int; 462 463 export fn execve(path: path, argv: *[*]nullable *const u8, 464 envp: *[*]nullable *const u8) errno = { 465 let res = libc_execve(cpath(path)?, argv, envp); 466 return *__errno(): errno; 467 }; 468 469 // umask 470 471 @symbol("umask") fn libc_umask(numask: mode_t) mode_t; 472 473 export fn umask(mode: mode_t) (mode_t | errno) = { 474 // Always successful on OpenBSD. 475 return libc_umask(mode); 476 }; 477 478 // chroot 479 480 @symbol("chroot") fn libc_chroot(dirname: *const u8) int; 481 482 export fn chroot(path: path) (void | errno) = { 483 let res = libc_chroot(cpath(path)?); 484 if (res == -1) { 485 return *__errno(): errno; 486 }; 487 }; 488 489 // getfsstat 490 // statfs 491 // fstatfs 492 // fhstatfs 493 // vfork 494 // gettimeofday 495 // settimeofday 496 // select 497 // kevent 498 499 @symbol("kevent") fn libc_kevent( 500 kq: int, 501 changelist: nullable *const [*]kevent, 502 nchanges: int, 503 eventlist: nullable *[*]kevent, 504 nevents: int, 505 timeout: nullable *const timespec 506 ) int; 507 508 // kevent() wrapper. Renamed to not conflict with the struct "kevent" 509 export fn kevent_poll( 510 kq: int, 511 changelist: nullable *const [*]kevent, 512 nchanges: int, 513 eventlist: nullable *[*]kevent, 514 nevents: int, 515 timeout: nullable *const timespec 516 ) (int | errno) = { 517 let res = libc_kevent(kq, changelist, nchanges, eventlist, nevents, 518 timeout); 519 if (res == -1) { 520 return *__errno(): errno; 521 }; 522 return res; 523 }; 524 525 // munmap 526 527 @symbol("munmap") fn libc_munmap(addr: *opaque, len_: size) int; 528 529 export fn munmap(addr: *opaque, len_: size) (void | errno) = { 530 let res = libc_munmap(addr, len_); 531 if (res == -1) { 532 return *__errno(): errno; 533 }; 534 }; 535 536 // mprotect 537 // madvise 538 // utimes 539 // futimes 540 // mquery 541 // getgroups 542 543 @symbol("getgroups") fn libc_getgroups(gidsetlen: int, gidset: *[*]gid_t) int; 544 545 export fn getgroups(gids: []gid_t) (uint | errno) = { 546 let res = libc_getgroups(len(gids): int, gids: *[*]gid_t); 547 if (res == -1) { 548 return *__errno(): errno; 549 }; 550 return res: uint; 551 }; 552 553 // setgroups 554 555 @symbol("setgroups") fn libc_setgroups( 556 ngroups: int, 557 gidset: *[*]gid_t, 558 ) int; 559 560 export fn setgroups(gids: []gid_t) (void | errno) = { 561 let res = libc_setgroups(len(gids): int, gids: *[*]gid_t); 562 if (res == -1) { 563 return *__errno(): errno; 564 }; 565 }; 566 567 // getpgrp 568 569 export @symbol("getpgrp") fn getpgrp() pid_t; 570 571 // setpgid 572 573 @symbol("setpgid") fn libc_setpgid(pid: pid_t, pgrp: pid_t) int; 574 575 export fn setpgid(pid: pid_t, pgrp: pid_t) (void | errno) = { 576 let res = libc_setpgid(pid, pgrp); 577 if (res == -1) { 578 return *__errno(): errno; 579 }; 580 }; 581 582 // futex 583 // utimensat 584 585 @symbol("utimensat") fn libc_utimensat( 586 fd: int, 587 path: *const u8, 588 times: *const [2]timespec, 589 flag: int 590 ) int; 591 592 export fn utimensat( 593 dirfd: int, 594 path: str, 595 ts: *[2]timespec, 596 flags: int 597 ) (void | errno) = { 598 let res = libc_utimensat(dirfd, cpath(path)?, ts, flags); 599 if (res == -1) { 600 return *__errno(): errno; 601 }; 602 }; 603 604 // futimens 605 606 @symbol("futimens") fn libc_futimens( 607 fd: int, 608 times: *const [2]timespec 609 ) int; 610 611 export fn futimens(fd: int, ts: *[2]timespec) (void | errno) = { 612 let res = libc_futimens(fd, ts); 613 if (res == -1) { 614 return *__errno(): errno; 615 }; 616 }; 617 618 // kbind 619 // clock_gettime 620 621 @symbol("clock_gettime") fn libc_clock_gettime(clock: int, now: *timespec) int; 622 623 export fn clock_gettime(clock: int, now: *timespec) (void | errno) = { 624 let res = libc_clock_gettime(clock, now); 625 if (res == -1) { 626 return *__errno(): errno; 627 }; 628 }; 629 630 // clock_settime 631 // clock_getres 632 // dup2 633 634 @symbol("dup2") fn libc_dup2(oldd: int, newd: int) int; 635 636 export fn dup2(oldfd: int, newfd: int) (int | errno) = { 637 let res = libc_dup2(oldfd, newfd); 638 if (res == -1) { 639 return *__errno(): errno; 640 }; 641 return res; 642 }; 643 644 // nanosleep 645 646 @symbol("nanosleep") fn libc_nanosleep( 647 timeout: *const timespec, 648 remainder: *timespec 649 ) int; 650 651 export fn nanosleep( 652 timeout: *const timespec, 653 remainder: *timespec 654 ) (void | errno) = { 655 let res = libc_nanosleep(timeout, remainder); 656 if (res == -1) { 657 return *__errno(): errno; 658 }; 659 }; 660 661 // fcntl 662 663 @symbol("fcntl") fn libc_fcntl(fd: int, cmd: int, arg: u64) int; 664 665 export type fcntl_arg = (void | int | *st_flock | *u64); 666 667 export fn fcntl(fd: int, cmd: int, arg: fcntl_arg) (int | errno) = { 668 let res = match (arg) { 669 case void => 670 yield libc_fcntl(fd, cmd, 0); 671 case let i: int => 672 yield libc_fcntl(fd, cmd, i: u64); 673 case let l: *st_flock => 674 yield libc_fcntl(fd, cmd, l: uintptr: u64); 675 case let u: *u64 => 676 yield libc_fcntl(fd, cmd, u: uintptr: u64); 677 }; 678 if (res == -1) { 679 return *__errno(): errno; 680 }; 681 return res; 682 }; 683 684 // accept4 685 686 @symbol("accept4") fn libc_accept4( 687 s: int, 688 addr: nullable *sockaddr, 689 adddrlen: nullable *u32, 690 flags: int 691 ) int; 692 693 export fn accept4( 694 sockfd: int, 695 addr: nullable *sockaddr, 696 addrlen: nullable *u32, 697 flags: int 698 ) (int | errno) = { 699 let res = libc_accept4(sockfd, addr, addrlen, flags); 700 if (res == -1) { 701 return *__errno(): errno; 702 }; 703 return res; 704 }; 705 706 // __thrsleep 707 // fsync 708 // setpriority 709 710 @symbol("setpriority") fn libc_setpriority( 711 which: int, 712 who: id_t, 713 prio: int 714 ) int; 715 716 export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = { 717 let res = libc_setpriority(which, who, prio); 718 if (res == -1) { 719 return *__errno(): errno; 720 }; 721 }; 722 723 // socket 724 725 @symbol("socket") fn libc_socket(domain: int, t: int, protocol: int) int; 726 727 export fn socket(domain: int, t: int, protocol: int) (int | errno) = { 728 let res = libc_socket(domain, t, protocol); 729 if (res == -1) { 730 return *__errno(): errno; 731 }; 732 return res; 733 }; 734 735 // connect 736 737 @symbol("connect") fn libc_connect( 738 sockfd: int, 739 addr: *const sockaddr, 740 addrlen: u32 741 ) int; 742 743 export fn connect( 744 sockfd: int, 745 addr: *const sockaddr, 746 addrlen: u32 747 ) (void | errno) = { 748 let res = libc_connect(sockfd, addr, addrlen); 749 if (res == -1) { 750 return *__errno(): errno; 751 }; 752 }; 753 754 // getdents 755 756 @symbol("getdents") fn libc_getdents(fd: int, buf: *opaque, nbytes: size) int; 757 758 export fn getdents(dirfd: int, buf: *opaque, nbytes: size) (int | errno) = { 759 let res = libc_getdents(dirfd, buf, nbytes); 760 if (res == -1) { 761 return *__errno(): errno; 762 }; 763 return res; 764 }; 765 766 // getpriority 767 768 @symbol("getpriority") fn libc_getpriority(which: int, who: id_t) int; 769 770 export fn getpriority(which: int, who: id_t) (int | errno) = { 771 let res = libc_getpriority(which, who); 772 if (res == -1) { 773 return *__errno(): errno; 774 }; 775 return res; 776 }; 777 778 // pipe2 779 780 @symbol("pipe2") fn libc_pipe2(pipefd: *[2]int, flags: int) int; 781 782 export fn pipe2(pipefd: *[2]int, flags: int) (void | errno) = { 783 let res = libc_pipe2(pipefd, flags); 784 if (res == -1) { 785 return *__errno(): errno; 786 }; 787 }; 788 789 // dup3 790 // sigreturn 791 // bind 792 793 @symbol("bind") fn libc_bind( 794 sockfd: int, 795 addr: *const sockaddr, 796 addrlen: u32 797 ) int; 798 799 export fn bind( 800 sockfd: int, 801 addr: *const sockaddr, 802 addrlen: u32 803 ) (void | errno) = { 804 let res = libc_bind(sockfd, addr, addrlen); 805 if (res == -1) { 806 return *__errno(): errno; 807 }; 808 }; 809 810 // setsockopt 811 812 @symbol("setsockopt") fn libc_setsockopt( 813 s: int, 814 level: int, 815 optname: int, 816 optval: *opaque, 817 optlen: u32 818 ) int; 819 820 export fn setsockopt( 821 sockfd: int, 822 level: int, 823 optname: int, 824 optval: *opaque, 825 optlen: u32 826 ) (void | errno) = { 827 let res = libc_setsockopt(sockfd, level, optname, optval, optlen); 828 if (res == -1) { 829 return *__errno(): errno; 830 }; 831 }; 832 833 // listen 834 835 @symbol("listen") fn libc_listen(s: int, backlog: int) int; 836 837 export fn listen(sockfd: int, backlog: u32) (void | errno) = { 838 let res = libc_listen(sockfd, backlog: int); 839 if (res == -1) { 840 return *__errno(): errno; 841 }; 842 }; 843 844 // chflagsat 845 // pledge 846 847 @symbol("pledge") fn libc_pledge( 848 promises: nullable *const u8, 849 execpromises: nullable *const u8 850 ) int; 851 852 // The "stdio" pledge is always needed. Passing [[nullpromise]] to promises or 853 // execpromises specifies to not change the current value. Check the pledge(2) 854 // manual page for more information about the differrent promises. 855 export fn pledge( 856 promises: (const str | nullpromise), 857 execpromises: (const str | nullpromise), 858 ) (void | errno) = { 859 let promises: nullable *u8 = match(promises) { 860 case let p: const str => 861 yield cpath(p)!; 862 case nullpromise => 863 yield null; 864 }; 865 866 let execpromises: nullable *u8 = match(execpromises) { 867 case let ep: const str => 868 yield copy_cpath(ep, pathbuf1)!; 869 case nullpromise => 870 yield null; 871 }; 872 873 let res = libc_pledge(promises, execpromises); 874 if (res == -1) { 875 return *__errno(): errno; 876 }; 877 }; 878 879 // ppoll 880 881 @symbol("ppoll") fn libc_ppoll( 882 fds: *[*]pollfd, 883 nfds: nfds_t, 884 timeout: const nullable *timespec, 885 mask: const nullable *sigset, 886 ) int; 887 888 export fn ppoll( 889 fds: *[*]pollfd, 890 nfds: nfds_t, 891 timeout: const nullable *timespec, 892 sigmask: const nullable *sigset, 893 ) (int | errno) = { 894 let ret = libc_ppoll(fds, nfds, timeout, sigmask); 895 if (ret == -1) { 896 return *__errno(): errno; 897 }; 898 return ret; 899 }; 900 901 // pselect 902 // sigsuspend 903 // sendsyslog 904 // unveil 905 906 @symbol("unveil") fn libc_unveil( 907 path: nullable *const u8, 908 permissions: nullable *const u8 909 ) int; 910 911 // After establishing a collection of path and permissions rules, future 912 // calls to [[unveil]] can be disabled by calling [[unveil_lock]]. 913 // Alternatively, [[pledge]] may be used to remove the "unveil" promise. 914 export fn unveil( 915 path: path, 916 permissions: const str, 917 ) (void | errno) = { 918 let res = libc_unveil(cpath(path)?, copy_cpath(permissions, pathbuf1)?); 919 if (res == -1) { 920 return *__errno(): errno; 921 }; 922 }; 923 924 // Disable future calls to [[unveil]]. 925 export fn unveil_lock() (void | errno) = { 926 let res = libc_unveil(null, null); 927 if (res == -1) { 928 return *__errno(): errno; 929 }; 930 }; 931 932 // __realpath 933 // recvmmsg 934 // sendmmsg 935 // getsockopt 936 937 @symbol("getsockopt") fn libc_getsockopt( 938 s: int, 939 level: int, 940 optname: int, 941 optval: nullable *opaque, 942 optlen: nullable *u32 943 ) int; 944 945 export fn getsockopt( 946 sockfd: int, 947 level: int, 948 optname: int, 949 optval: nullable *opaque, 950 optlen: nullable *u32 951 ) (void | errno) = { 952 let res = libc_getsockopt(sockfd, level, optname, optval, optlen); 953 if (res == -1) { 954 return *__errno(): errno; 955 }; 956 }; 957 958 // thrkill 959 // readv 960 961 @symbol("readv") fn libc_readv(d: int, iov: const *[*]iovec, iovcnt: int) size; 962 963 export fn readv(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 964 let res: u64 = libc_readv(fd, iov, iovcnt); 965 966 if (res == -1) { 967 return *__errno(): errno; 968 }; 969 return res; 970 }; 971 972 // writev 973 974 @symbol("writev") fn libc_writev(d: int, iov: const *[*]iovec, iovcnt: int) size; 975 976 export fn writev(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 977 let res: u64 = libc_writev(fd, iov, iovcnt); 978 979 if (res == -1) { 980 return *__errno(): errno; 981 }; 982 return res; 983 }; 984 985 // kill 986 987 @symbol("kill") fn libc_kill(pid: int, signal: int) int; 988 989 export fn kill(pid: int, signal: int) (void | errno) = { 990 let res = libc_kill(pid, signal); 991 if (res == -1) { 992 return *__errno(): errno; 993 }; 994 }; 995 996 // fchown 997 998 @symbol("fchown") fn libc_fchown( 999 fd: int, 1000 owner: uid_t, 1001 group: gid_t 1002 ) int; 1003 1004 export fn fchown(fd: int, uid: uid_t, gid: gid_t) (void | errno) = { 1005 let res = libc_fchown(fd, uid, gid); 1006 if (res == -1) { 1007 return *__errno(): errno; 1008 }; 1009 }; 1010 1011 // fchmod 1012 1013 @symbol("fchmod") fn libc_fchmod( 1014 fd: int, 1015 mode: uint 1016 ) int; 1017 1018 export fn fchmod(fd: int, mode: uint) (void | errno) = { 1019 let res = libc_fchmod(fd, mode); 1020 if (res == -1) { 1021 return *__errno(): errno; 1022 }; 1023 }; 1024 1025 // setreuid 1026 // setregid 1027 // rename 1028 // flock 1029 1030 @symbol("flock") fn libc_flock(fd: int, operation: int) int; 1031 1032 export fn flock(fd: int, op: int) (void | errno) = { 1033 let res = libc_flock(fd, op); 1034 if (res == -1) { 1035 return *__errno(): errno; 1036 }; 1037 }; 1038 1039 // mkfifo 1040 // sendto 1041 1042 @symbol("sendto") fn libc_sendto( 1043 s: int, 1044 msg: *opaque, 1045 length: size, 1046 flags: int, 1047 to: nullable *sockaddr, 1048 tolen: socklen_t 1049 ) i64; 1050 1051 export fn sendto( 1052 sockfd: int, 1053 buf: *opaque, 1054 length: size, 1055 flags: int, 1056 dest_addr: nullable *sockaddr, 1057 addrlen: u32 1058 ) (size | errno) = { 1059 let res = libc_sendto(sockfd, buf, length, flags, dest_addr, addrlen); 1060 if (res == -1) { 1061 return *__errno(): errno; 1062 }; 1063 return res: size; 1064 }; 1065 1066 // shutdown 1067 1068 @symbol("shutdown") fn libc_shutdown(s: int, how: int) int; 1069 1070 export fn shutdown(s: int, how: int) (void | errno) = { 1071 let res = libc_shutdown(s, how); 1072 if (res == -1) { 1073 return *__errno(): errno; 1074 }; 1075 }; 1076 1077 // socketpair 1078 1079 @symbol("socketpair") fn libc_socketpair( 1080 domain: int, 1081 type_: int, 1082 protocol: int, 1083 sv: *[*]int 1084 ) int; 1085 1086 export fn socketpair( 1087 domain: int, 1088 type_: int, 1089 protocol: int, 1090 sv: *[*]int 1091 ) (void | errno) = { 1092 let res = libc_socketpair(domain, type_, protocol, sv); 1093 if (res == -1) { 1094 return *__errno(): errno; 1095 }; 1096 1097 }; 1098 // mkdir 1099 // rmdir 1100 // adjtime 1101 // getlogin_r 1102 // getthrname 1103 // setthrname 1104 // pinsyscall 1105 1106 // setsid 1107 1108 @symbol("setsid") fn libc_setsid() pid_t; 1109 1110 export fn setsid() (void | errno) = { 1111 let res = libc_setsid(); 1112 if (res == -1) { 1113 return *__errno(): errno; 1114 }; 1115 }; 1116 1117 // quotactl 1118 // ypconnect 1119 // nfssvc 1120 // mimmutable 1121 // waitid 1122 // getfh 1123 // __tmpfd 1124 // sysarch 1125 // lseek 1126 1127 @symbol("lseek") fn libc_lseek(fildes: int, pos: i64, whence: int) i64; 1128 1129 export fn lseek(fd: int, off: i64, whence: int) (i64 | errno) = { 1130 let res = libc_lseek(fd, off, whence); 1131 if (res == -1) { 1132 return *__errno(): errno; 1133 }; 1134 return res; 1135 }; 1136 1137 // truncate 1138 // ftruncate 1139 1140 @symbol("ftruncate") fn libc_ftruncate(fd: int, length: i64) int; 1141 1142 export fn ftruncate(fd: int, length: i64) (void | errno) = { 1143 let res = libc_ftruncate(fd, length); 1144 if (res == -1) { 1145 return *__errno(): errno; 1146 }; 1147 }; 1148 1149 // pread 1150 // pwrite 1151 // preadv 1152 // pwritev 1153 // setgid 1154 1155 @symbol("setgid") fn libc_setgid(gid: gid_t) int; 1156 1157 export fn setgid(gid: gid_t) (void | errno) = { 1158 let res = libc_setgid(gid); 1159 if (res == -1) { 1160 return *__errno(): errno; 1161 }; 1162 }; 1163 1164 // setegid 1165 1166 @symbol("setegid") fn libc_setegid(gid: gid_t) int; 1167 1168 export fn setegid(gid: gid_t) (void | errno) = { 1169 let res = libc_setegid(gid); 1170 if (res == -1) { 1171 return *__errno(): errno; 1172 }; 1173 }; 1174 1175 // seteuid 1176 1177 @symbol("seteuid") fn libc_seteuid(uid: uid_t) int; 1178 1179 export fn seteuid(uid: uid_t) (void | errno) = { 1180 let res = libc_seteuid(uid); 1181 if (res == -1) { 1182 return *__errno(): errno; 1183 }; 1184 }; 1185 1186 // pathconf 1187 // fpathconf 1188 // swapctl 1189 // getrlimit 1190 // setrlimit 1191 // sysctl 1192 1193 @symbol("sysctl") fn libc_sysctl( 1194 name: *[*]int, 1195 namelen: uint, 1196 oldp: nullable *opaque, 1197 oldlenp: nullable *size, 1198 newp: nullable *opaque, 1199 newlen: size 1200 ) int; 1201 1202 export fn sysctl( 1203 name: []int, 1204 namelen: uint, 1205 oldp: nullable *opaque, 1206 oldlenp: nullable *size, 1207 newp: nullable *opaque, 1208 newlen: size 1209 ) (void | errno) = { 1210 let res = libc_sysctl(name: *[*]int, namelen, oldp, oldlenp, newp, newlen); 1211 if (res == -1) { 1212 return *__errno(): errno; 1213 }; 1214 }; 1215 1216 // mlock 1217 // munlock 1218 // getpgid 1219 1220 @symbol("getpgid") fn libc_getpgid(pid: pid_t) pid_t; 1221 1222 export fn getpgid(pid: pid_t) (pid_t | errno) = { 1223 let res = libc_getpgid(pid); 1224 if (res == -1) { 1225 return *__errno(): errno; 1226 }; 1227 1228 return res; 1229 }; 1230 1231 // utrace 1232 // semget 1233 // msgget 1234 // msgsnd 1235 // msgrcv 1236 // shmat 1237 // shmdt 1238 // minherit 1239 // poll 1240 // issetugid 1241 // lchown 1242 1243 // getsid 1244 1245 @symbol("getsid") fn libc_getsid(pid: pid_t) pid_t; 1246 1247 export fn getsid(pid: pid_t) (pid_t | errno) = { 1248 let res = libc_getsid(pid); 1249 if (res == -1) { 1250 return *__errno(): errno; 1251 }; 1252 return res; 1253 }; 1254 1255 // msync 1256 // pipe 1257 // fhopen 1258 // kqueue 1259 1260 @symbol("kqueue") fn libc_kqueue() int; 1261 1262 export fn kqueue() (int | errno) = { 1263 let res = libc_kqueue(); 1264 if (res == -1) { 1265 return *__errno(): errno; 1266 }; 1267 1268 return res; 1269 }; 1270 1271 // kqueue1 1272 1273 @symbol("kqueue1") fn libc_kqueue1(flags: int) int; 1274 1275 export fn kqueue1(flags: int) (int | errno) = { 1276 let res = libc_kqueue1(flags); 1277 if (res == -1) { 1278 return *__errno(): errno; 1279 }; 1280 1281 return res; 1282 }; 1283 1284 // mlockall 1285 // munlockall 1286 // getresuid 1287 // setresuid 1288 // getresgid 1289 // setresgid 1290 // closefrom 1291 // sigaltstack 1292 // shmget 1293 // semop 1294 // fhstat 1295 // __semctl 1296 // shmctl 1297 // msgctl 1298 // sched_yield 1299 // getthrid 1300 // __thrwakeup 1301 // __threxit 1302 // __thrsigdivert 1303 // getcwd 1304 1305 @symbol("getcwd") fn libc_getcwd(buf: *u8, bufsz: size) *u8; 1306 1307 // The return value is statically allocated and must be duplicated before 1308 // calling getcwd again. 1309 export fn getcwd() (*const u8 | errno) = { 1310 static let pathbuf: [PATH_MAX]u8 = [0...]; 1311 1312 let res = libc_getcwd(&pathbuf: *u8, len(pathbuf)); 1313 if (res == null) { 1314 return *__errno(): errno; 1315 }; 1316 1317 return res; 1318 }; 1319 1320 // adjfreq 1321 // setrtable 1322 // getrtable 1323 // faccessat 1324 // fchmodat 1325 1326 @symbol("fchmodat") fn libc_fchmodat( 1327 fd: int, 1328 path: *const u8, 1329 mode: mode_t, 1330 flag: int 1331 ) int; 1332 1333 export fn fchmodat( 1334 dirfd: int, 1335 path: path, 1336 mode: mode_t, 1337 flag: int 1338 ) (void | errno) = { 1339 let res = libc_fchmodat(dirfd, cpath(path)?, mode, flag); 1340 if (res == -1) { 1341 return *__errno(): errno; 1342 }; 1343 }; 1344 1345 // fchownat 1346 1347 @symbol("fchownat") fn libc_fchownat( 1348 fd: int, 1349 path: *const u8, 1350 owner: uid_t, 1351 group: gid_t, 1352 flag: int 1353 ) int; 1354 1355 export fn fchownat( 1356 dirfd: int, 1357 path: path, 1358 uid: uid_t, 1359 gid: gid_t, 1360 flag: int 1361 ) (void | errno) = { 1362 let res = libc_fchownat(dirfd, cpath(path)?, uid, gid, flag); 1363 if (res == -1) { 1364 return *__errno(): errno; 1365 }; 1366 }; 1367 1368 // linkat 1369 1370 @symbol("linkat") fn libc_linkat( 1371 fd1: int, 1372 name1: *const u8, 1373 fd2: int, 1374 name2: *const u8, 1375 flag: int 1376 ) int; 1377 1378 export fn linkat( 1379 olddirfd: int, 1380 oldpath: path, 1381 newdirfd: int, 1382 newpath: path, 1383 flags: int, 1384 ) (void | errno) = { 1385 let oldpath = cpath(oldpath)?; 1386 let newpath = copy_cpath(newpath, pathbuf1)?; 1387 1388 let res = libc_linkat(olddirfd, oldpath, newdirfd, newpath, flags); 1389 if (res == -1) { 1390 return *__errno(): errno; 1391 }; 1392 }; 1393 1394 // mkdirat 1395 1396 @symbol("mkdirat") fn libc_mkdirat(fd: int, path: *const u8, mode: mode_t) int; 1397 1398 export fn mkdirat(dirfd: int, path: path, mode: mode_t) (void | errno) = { 1399 let res = libc_mkdirat(dirfd, cpath(path)?, mode); 1400 if (res == -1) { 1401 return *__errno(): errno; 1402 }; 1403 }; 1404 1405 // mkfifoat 1406 // mknodat 1407 1408 @symbol("mknodat") fn libc_mknodat( 1409 fd: int, 1410 path: *const u8, 1411 mode: mode_t, 1412 dev: dev_t 1413 ) int; 1414 1415 // The OpenBSD implementation of mknodat *only* supports FIFO and 1416 // device special files. 1417 export fn mknodat( 1418 dirfd: int, 1419 path: path, 1420 mode: mode_t, 1421 dev: dev_t, 1422 ) (void | errno) = { 1423 let res = libc_mknodat(dirfd, cpath(path)?, mode, dev); 1424 if (res == -1) { 1425 return *__errno(): errno; 1426 }; 1427 }; 1428 1429 // openat 1430 1431 @symbol("openat") fn libc_openat( 1432 fd: int, 1433 path: *const u8, 1434 flags: int, 1435 mode: uint, 1436 ) int; 1437 1438 export fn openat( 1439 dirfd: int, 1440 path: path, 1441 flags: int, 1442 mode: uint, 1443 ) (int | errno) = { 1444 let res = libc_openat(dirfd, cpath(path)?, flags, mode); 1445 if (res == -1) { 1446 return *__errno(): errno; 1447 }; 1448 return res; 1449 }; 1450 1451 // readlinkat 1452 1453 @symbol("readlinkat") fn libc_readlinkat( 1454 fd: int, 1455 path: *const u8, 1456 buf: *u8, 1457 bufsiz: size 1458 ) i64; 1459 1460 export fn readlinkat( 1461 dirfd: int, 1462 path: path, 1463 buf: []u8, 1464 ) (size | errno) = { 1465 let res = libc_readlinkat(dirfd, cpath(path)?, buf: *[*]u8: *u8, len(buf)); 1466 if (res == -1) { 1467 return *__errno(): errno; 1468 }; 1469 return res: size; 1470 }; 1471 1472 // renameat 1473 1474 @symbol("renameat") fn libc_renameat( 1475 fromfd: int, 1476 from: *const u8, 1477 tofd: int, 1478 to: *const u8 1479 ) int; 1480 1481 export fn renameat( 1482 olddirfd: int, 1483 oldpath: str, 1484 newdirfd: int, 1485 newpath: str, 1486 ) (void | errno) = { 1487 let newpath = copy_cpath(newpath, pathbuf1)?; 1488 1489 let res = libc_renameat(olddirfd, cpath(oldpath)?, newdirfd, 1490 newpath); 1491 if (res == -1) { 1492 return *__errno(): errno; 1493 }; 1494 }; 1495 1496 // symlinkat 1497 1498 @symbol("symlinkat") fn libc_symlinkat( 1499 name1: *const u8, 1500 fd: int, 1501 name2: *const u8 1502 ) int; 1503 1504 export fn symlinkat( 1505 target: path, 1506 newdirfd: int, 1507 linkpath: path, 1508 ) (void | errno) = { 1509 let target = cpath(target)?; 1510 let linkpath = copy_cpath(linkpath, pathbuf1)?; 1511 1512 let res = libc_symlinkat(target, newdirfd, linkpath); 1513 if (res == -1) { 1514 return *__errno(): errno; 1515 }; 1516 }; 1517 1518 // unlinkat 1519 1520 @symbol("unlinkat") fn libc_unlinkat(fd: int, path: *const u8, flag: int) int; 1521 1522 export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { 1523 let res = libc_unlinkat(dirfd, cpath(path)?, flags); 1524 if (res == -1) { 1525 return *__errno(): errno; 1526 }; 1527 }; 1528 1529 // __set_tcb 1530 // __get_tcb