syscalls.ha (29142B)
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 // clock_settime 621 622 @symbol("clock_gettime") fn libc_clock_gettime(clock: int, now: *timespec) int; 623 624 export fn clock_gettime(clock: int, now: *timespec) (void | errno) = { 625 let res = libc_clock_gettime(clock, now); 626 if (res == -1) { 627 return *__errno(): errno; 628 }; 629 }; 630 631 @symbol("clock_settime") fn libc_clock_settime(clock: int, now: *const timespec) int; 632 633 export fn clock_settime(clock: int, now: *const timespec) (void | errno) = { 634 let res = libc_clock_settime(clock, now); 635 if (res == -1) { 636 return *__errno(): errno; 637 }; 638 }; 639 640 // clock_getres 641 // dup2 642 643 @symbol("dup2") fn libc_dup2(oldd: int, newd: int) int; 644 645 export fn dup2(oldfd: int, newfd: int) (int | errno) = { 646 let res = libc_dup2(oldfd, newfd); 647 if (res == -1) { 648 return *__errno(): errno; 649 }; 650 return res; 651 }; 652 653 // nanosleep 654 655 @symbol("nanosleep") fn libc_nanosleep( 656 timeout: *const timespec, 657 remainder: *timespec 658 ) int; 659 660 export fn nanosleep( 661 timeout: *const timespec, 662 remainder: *timespec 663 ) (void | errno) = { 664 let res = libc_nanosleep(timeout, remainder); 665 if (res == -1) { 666 return *__errno(): errno; 667 }; 668 }; 669 670 // fcntl 671 672 @symbol("fcntl") fn libc_fcntl(fd: int, cmd: int, arg: u64) int; 673 674 export type fcntl_arg = (void | int | *st_flock | *u64); 675 676 export fn fcntl(fd: int, cmd: int, arg: fcntl_arg) (int | errno) = { 677 let res = match (arg) { 678 case void => 679 yield libc_fcntl(fd, cmd, 0); 680 case let i: int => 681 yield libc_fcntl(fd, cmd, i: u64); 682 case let l: *st_flock => 683 yield libc_fcntl(fd, cmd, l: uintptr: u64); 684 case let u: *u64 => 685 yield libc_fcntl(fd, cmd, u: uintptr: u64); 686 }; 687 if (res == -1) { 688 return *__errno(): errno; 689 }; 690 return res; 691 }; 692 693 // accept4 694 695 @symbol("accept4") fn libc_accept4( 696 s: int, 697 addr: nullable *sockaddr, 698 adddrlen: nullable *u32, 699 flags: int 700 ) int; 701 702 export fn accept4( 703 sockfd: int, 704 addr: nullable *sockaddr, 705 addrlen: nullable *u32, 706 flags: int 707 ) (int | errno) = { 708 let res = libc_accept4(sockfd, addr, addrlen, flags); 709 if (res == -1) { 710 return *__errno(): errno; 711 }; 712 return res; 713 }; 714 715 // __thrsleep 716 717 // fsync 718 @symbol("fsync") fn libc_fsync(fd: int) int; 719 720 export fn fsync(fd: int) (void | errno) = { 721 let res = libc_fsync(fd); 722 if (res == -1) { 723 return *__errno(): errno; 724 }; 725 return res; 726 }; 727 728 // fdatasync 729 @symbol("fdatasync") fn libc_fdatasync(fd: int) int; 730 731 export fn fdatasync(fd: int) (void | errno) = { 732 let res = libc_fdatasync(fd); 733 if (res == -1) { 734 return *__errno(): errno; 735 }; 736 return res; 737 }; 738 739 // setpriority 740 741 @symbol("setpriority") fn libc_setpriority( 742 which: int, 743 who: id_t, 744 prio: int 745 ) int; 746 747 export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = { 748 let res = libc_setpriority(which, who, prio); 749 if (res == -1) { 750 return *__errno(): errno; 751 }; 752 }; 753 754 // socket 755 756 @symbol("socket") fn libc_socket(domain: int, t: int, protocol: int) int; 757 758 export fn socket(domain: int, t: int, protocol: int) (int | errno) = { 759 let res = libc_socket(domain, t, protocol); 760 if (res == -1) { 761 return *__errno(): errno; 762 }; 763 return res; 764 }; 765 766 // connect 767 768 @symbol("connect") fn libc_connect( 769 sockfd: int, 770 addr: *const sockaddr, 771 addrlen: u32 772 ) int; 773 774 export fn connect( 775 sockfd: int, 776 addr: *const sockaddr, 777 addrlen: u32 778 ) (void | errno) = { 779 let res = libc_connect(sockfd, addr, addrlen); 780 if (res == -1) { 781 return *__errno(): errno; 782 }; 783 }; 784 785 // getdents 786 787 @symbol("getdents") fn libc_getdents(fd: int, buf: *opaque, nbytes: size) int; 788 789 export fn getdents(dirfd: int, buf: *opaque, nbytes: size) (int | errno) = { 790 let res = libc_getdents(dirfd, buf, nbytes); 791 if (res == -1) { 792 return *__errno(): errno; 793 }; 794 return res; 795 }; 796 797 // getpriority 798 799 @symbol("getpriority") fn libc_getpriority(which: int, who: id_t) int; 800 801 export fn getpriority(which: int, who: id_t) (int | errno) = { 802 let res = libc_getpriority(which, who); 803 if (res == -1) { 804 return *__errno(): errno; 805 }; 806 return res; 807 }; 808 809 // pipe2 810 811 @symbol("pipe2") fn libc_pipe2(pipefd: *[2]int, flags: int) int; 812 813 export fn pipe2(pipefd: *[2]int, flags: int) (void | errno) = { 814 let res = libc_pipe2(pipefd, flags); 815 if (res == -1) { 816 return *__errno(): errno; 817 }; 818 }; 819 820 // dup3 821 // sigreturn 822 // bind 823 824 @symbol("bind") fn libc_bind( 825 sockfd: int, 826 addr: *const sockaddr, 827 addrlen: u32 828 ) int; 829 830 export fn bind( 831 sockfd: int, 832 addr: *const sockaddr, 833 addrlen: u32 834 ) (void | errno) = { 835 let res = libc_bind(sockfd, addr, addrlen); 836 if (res == -1) { 837 return *__errno(): errno; 838 }; 839 }; 840 841 // setsockopt 842 843 @symbol("setsockopt") fn libc_setsockopt( 844 s: int, 845 level: int, 846 optname: int, 847 optval: *opaque, 848 optlen: u32 849 ) int; 850 851 export fn setsockopt( 852 sockfd: int, 853 level: int, 854 optname: int, 855 optval: *opaque, 856 optlen: u32 857 ) (void | errno) = { 858 let res = libc_setsockopt(sockfd, level, optname, optval, optlen); 859 if (res == -1) { 860 return *__errno(): errno; 861 }; 862 }; 863 864 // listen 865 866 @symbol("listen") fn libc_listen(s: int, backlog: int) int; 867 868 export fn listen(sockfd: int, backlog: u32) (void | errno) = { 869 let res = libc_listen(sockfd, backlog: int); 870 if (res == -1) { 871 return *__errno(): errno; 872 }; 873 }; 874 875 // chflagsat 876 // pledge 877 878 @symbol("pledge") fn libc_pledge( 879 promises: nullable *const u8, 880 execpromises: nullable *const u8 881 ) int; 882 883 // The "stdio" pledge is always needed. Passing [[nullpromise]] to promises or 884 // execpromises specifies to not change the current value. Check the pledge(2) 885 // manual page for more information about the differrent promises. 886 export fn pledge( 887 promises: (const str | nullpromise), 888 execpromises: (const str | nullpromise), 889 ) (void | errno) = { 890 let promises: nullable *u8 = match(promises) { 891 case let p: const str => 892 yield cpath(p)!; 893 case nullpromise => 894 yield null; 895 }; 896 897 let execpromises: nullable *u8 = match(execpromises) { 898 case let ep: const str => 899 yield copy_cpath(ep, pathbuf1)!; 900 case nullpromise => 901 yield null; 902 }; 903 904 let res = libc_pledge(promises, execpromises); 905 if (res == -1) { 906 return *__errno(): errno; 907 }; 908 }; 909 910 // ppoll 911 912 @symbol("ppoll") fn libc_ppoll( 913 fds: *[*]pollfd, 914 nfds: nfds_t, 915 timeout: const nullable *timespec, 916 mask: const nullable *sigset, 917 ) int; 918 919 export fn ppoll( 920 fds: *[*]pollfd, 921 nfds: nfds_t, 922 timeout: const nullable *timespec, 923 sigmask: const nullable *sigset, 924 ) (int | errno) = { 925 let ret = libc_ppoll(fds, nfds, timeout, sigmask); 926 if (ret == -1) { 927 return *__errno(): errno; 928 }; 929 return ret; 930 }; 931 932 // pselect 933 // sigsuspend 934 // sendsyslog 935 // unveil 936 937 @symbol("unveil") fn libc_unveil( 938 path: nullable *const u8, 939 permissions: nullable *const u8 940 ) int; 941 942 // After establishing a collection of path and permissions rules, future 943 // calls to [[unveil]] can be disabled by calling [[unveil_lock]]. 944 // Alternatively, [[pledge]] may be used to remove the "unveil" promise. 945 export fn unveil( 946 path: path, 947 permissions: const str, 948 ) (void | errno) = { 949 let res = libc_unveil(cpath(path)?, copy_cpath(permissions, pathbuf1)?); 950 if (res == -1) { 951 return *__errno(): errno; 952 }; 953 }; 954 955 // Disable future calls to [[unveil]]. 956 export fn unveil_lock() (void | errno) = { 957 let res = libc_unveil(null, null); 958 if (res == -1) { 959 return *__errno(): errno; 960 }; 961 }; 962 963 // __realpath 964 // recvmmsg 965 // sendmmsg 966 // getsockopt 967 968 @symbol("getsockopt") fn libc_getsockopt( 969 s: int, 970 level: int, 971 optname: int, 972 optval: nullable *opaque, 973 optlen: nullable *u32 974 ) int; 975 976 export fn getsockopt( 977 sockfd: int, 978 level: int, 979 optname: int, 980 optval: nullable *opaque, 981 optlen: nullable *u32 982 ) (void | errno) = { 983 let res = libc_getsockopt(sockfd, level, optname, optval, optlen); 984 if (res == -1) { 985 return *__errno(): errno; 986 }; 987 }; 988 989 // thrkill 990 // readv 991 992 @symbol("readv") fn libc_readv(d: int, iov: const *[*]iovec, iovcnt: int) size; 993 994 export fn readv(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 995 let res: u64 = libc_readv(fd, iov, iovcnt); 996 997 if (res == -1) { 998 return *__errno(): errno; 999 }; 1000 return res; 1001 }; 1002 1003 // writev 1004 1005 @symbol("writev") fn libc_writev(d: int, iov: const *[*]iovec, iovcnt: int) size; 1006 1007 export fn writev(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 1008 let res: u64 = libc_writev(fd, iov, iovcnt); 1009 1010 if (res == -1) { 1011 return *__errno(): errno; 1012 }; 1013 return res; 1014 }; 1015 1016 // kill 1017 1018 @symbol("kill") fn libc_kill(pid: pid_t, signal: int) int; 1019 1020 export fn kill(pid: pid_t, signal: int) (void | errno) = { 1021 let res = libc_kill(pid, signal); 1022 if (res == -1) { 1023 return *__errno(): errno; 1024 }; 1025 }; 1026 1027 // fchown 1028 1029 @symbol("fchown") fn libc_fchown( 1030 fd: int, 1031 owner: uid_t, 1032 group: gid_t 1033 ) int; 1034 1035 export fn fchown(fd: int, uid: uid_t, gid: gid_t) (void | errno) = { 1036 let res = libc_fchown(fd, uid, gid); 1037 if (res == -1) { 1038 return *__errno(): errno; 1039 }; 1040 }; 1041 1042 // fchmod 1043 1044 @symbol("fchmod") fn libc_fchmod( 1045 fd: int, 1046 mode: uint 1047 ) int; 1048 1049 export fn fchmod(fd: int, mode: uint) (void | errno) = { 1050 let res = libc_fchmod(fd, mode); 1051 if (res == -1) { 1052 return *__errno(): errno; 1053 }; 1054 }; 1055 1056 // setreuid 1057 // setregid 1058 // rename 1059 // flock 1060 1061 @symbol("flock") fn libc_flock(fd: int, operation: int) int; 1062 1063 export fn flock(fd: int, op: int) (void | errno) = { 1064 let res = libc_flock(fd, op); 1065 if (res == -1) { 1066 return *__errno(): errno; 1067 }; 1068 }; 1069 1070 // mkfifo 1071 // sendto 1072 1073 @symbol("sendto") fn libc_sendto( 1074 s: int, 1075 msg: *opaque, 1076 length: size, 1077 flags: int, 1078 to: nullable *sockaddr, 1079 tolen: socklen_t 1080 ) i64; 1081 1082 export fn sendto( 1083 sockfd: int, 1084 buf: *opaque, 1085 length: size, 1086 flags: int, 1087 dest_addr: nullable *sockaddr, 1088 addrlen: u32 1089 ) (size | errno) = { 1090 let res = libc_sendto(sockfd, buf, length, flags, dest_addr, addrlen); 1091 if (res == -1) { 1092 return *__errno(): errno; 1093 }; 1094 return res: size; 1095 }; 1096 1097 // shutdown 1098 1099 @symbol("shutdown") fn libc_shutdown(s: int, how: int) int; 1100 1101 export fn shutdown(s: int, how: int) (void | errno) = { 1102 let res = libc_shutdown(s, how); 1103 if (res == -1) { 1104 return *__errno(): errno; 1105 }; 1106 }; 1107 1108 // socketpair 1109 1110 @symbol("socketpair") fn libc_socketpair( 1111 domain: int, 1112 type_: int, 1113 protocol: int, 1114 sv: *[*]int 1115 ) int; 1116 1117 export fn socketpair( 1118 domain: int, 1119 type_: int, 1120 protocol: int, 1121 sv: *[*]int 1122 ) (void | errno) = { 1123 let res = libc_socketpair(domain, type_, protocol, sv); 1124 if (res == -1) { 1125 return *__errno(): errno; 1126 }; 1127 1128 }; 1129 // mkdir 1130 // rmdir 1131 // adjtime 1132 // getlogin_r 1133 // getthrname 1134 // setthrname 1135 // pinsyscall 1136 1137 // setsid 1138 1139 @symbol("setsid") fn libc_setsid() pid_t; 1140 1141 export fn setsid() (void | errno) = { 1142 let res = libc_setsid(); 1143 if (res == -1) { 1144 return *__errno(): errno; 1145 }; 1146 }; 1147 1148 // quotactl 1149 // ypconnect 1150 // nfssvc 1151 // mimmutable 1152 // waitid 1153 // getfh 1154 // __tmpfd 1155 // sysarch 1156 // lseek 1157 1158 @symbol("lseek") fn libc_lseek(fildes: int, pos: i64, whence: int) i64; 1159 1160 export fn lseek(fd: int, off: i64, whence: int) (i64 | errno) = { 1161 let res = libc_lseek(fd, off, whence); 1162 if (res == -1) { 1163 return *__errno(): errno; 1164 }; 1165 return res; 1166 }; 1167 1168 // truncate 1169 // ftruncate 1170 1171 @symbol("ftruncate") fn libc_ftruncate(fd: int, length: i64) int; 1172 1173 export fn ftruncate(fd: int, length: i64) (void | errno) = { 1174 let res = libc_ftruncate(fd, length); 1175 if (res == -1) { 1176 return *__errno(): errno; 1177 }; 1178 }; 1179 1180 // pread 1181 // pwrite 1182 // preadv 1183 // pwritev 1184 // setgid 1185 1186 @symbol("setgid") fn libc_setgid(gid: gid_t) int; 1187 1188 export fn setgid(gid: gid_t) (void | errno) = { 1189 let res = libc_setgid(gid); 1190 if (res == -1) { 1191 return *__errno(): errno; 1192 }; 1193 }; 1194 1195 // setegid 1196 1197 @symbol("setegid") fn libc_setegid(gid: gid_t) int; 1198 1199 export fn setegid(gid: gid_t) (void | errno) = { 1200 let res = libc_setegid(gid); 1201 if (res == -1) { 1202 return *__errno(): errno; 1203 }; 1204 }; 1205 1206 // seteuid 1207 1208 @symbol("seteuid") fn libc_seteuid(uid: uid_t) int; 1209 1210 export fn seteuid(uid: uid_t) (void | errno) = { 1211 let res = libc_seteuid(uid); 1212 if (res == -1) { 1213 return *__errno(): errno; 1214 }; 1215 }; 1216 1217 // pathconf 1218 // fpathconf 1219 // swapctl 1220 // getrlimit 1221 // setrlimit 1222 // sysctl 1223 1224 @symbol("sysctl") fn libc_sysctl( 1225 name: *[*]int, 1226 namelen: uint, 1227 oldp: nullable *opaque, 1228 oldlenp: nullable *size, 1229 newp: nullable *opaque, 1230 newlen: size 1231 ) int; 1232 1233 export fn sysctl( 1234 name: []int, 1235 namelen: uint, 1236 oldp: nullable *opaque, 1237 oldlenp: nullable *size, 1238 newp: nullable *opaque, 1239 newlen: size 1240 ) (void | errno) = { 1241 let res = libc_sysctl(name: *[*]int, namelen, oldp, oldlenp, newp, newlen); 1242 if (res == -1) { 1243 return *__errno(): errno; 1244 }; 1245 }; 1246 1247 // mlock 1248 // munlock 1249 // getpgid 1250 1251 @symbol("getpgid") fn libc_getpgid(pid: pid_t) pid_t; 1252 1253 export fn getpgid(pid: pid_t) (pid_t | errno) = { 1254 let res = libc_getpgid(pid); 1255 if (res == -1) { 1256 return *__errno(): errno; 1257 }; 1258 1259 return res; 1260 }; 1261 1262 // utrace 1263 // semget 1264 // msgget 1265 // msgsnd 1266 // msgrcv 1267 // shmat 1268 // shmdt 1269 // minherit 1270 // poll 1271 // issetugid 1272 // lchown 1273 1274 // shm_open 1275 1276 @symbol("shm_open") fn libc_shm_open(path: *const u8, flags: int, mode: mode_t) int; 1277 1278 export fn shm_open(path: path, flags: int, mode: mode_t) (int | errno) = { 1279 let res = libc_shm_open(cpath(path)?, flags, mode); 1280 if (res == -1) { 1281 return *__errno(): errno; 1282 }; 1283 return res; 1284 }; 1285 1286 // shm_unlink 1287 1288 @symbol("shm_unlink") fn libc_shm_unlink(path: *const u8) int; 1289 1290 export fn shm_unlink(path: path) (void | errno) = { 1291 let res = libc_shm_unlink(cpath(path)?); 1292 if (res == -1) { 1293 return *__errno(): errno; 1294 }; 1295 }; 1296 1297 // getsid 1298 1299 @symbol("getsid") fn libc_getsid(pid: pid_t) pid_t; 1300 1301 export fn getsid(pid: pid_t) (pid_t | errno) = { 1302 let res = libc_getsid(pid); 1303 if (res == -1) { 1304 return *__errno(): errno; 1305 }; 1306 return res; 1307 }; 1308 1309 // msync 1310 // pipe 1311 // fhopen 1312 // kqueue 1313 1314 @symbol("kqueue") fn libc_kqueue() int; 1315 1316 export fn kqueue() (int | errno) = { 1317 let res = libc_kqueue(); 1318 if (res == -1) { 1319 return *__errno(): errno; 1320 }; 1321 1322 return res; 1323 }; 1324 1325 // kqueue1 1326 1327 @symbol("kqueue1") fn libc_kqueue1(flags: int) int; 1328 1329 export fn kqueue1(flags: int) (int | errno) = { 1330 let res = libc_kqueue1(flags); 1331 if (res == -1) { 1332 return *__errno(): errno; 1333 }; 1334 1335 return res; 1336 }; 1337 1338 // mlockall 1339 // munlockall 1340 // getresuid 1341 // setresuid 1342 // getresgid 1343 // setresgid 1344 // closefrom 1345 // sigaltstack 1346 // shmget 1347 // semop 1348 // fhstat 1349 // __semctl 1350 // shmctl 1351 // msgctl 1352 // sched_yield 1353 // getthrid 1354 // __thrwakeup 1355 // __threxit 1356 // __thrsigdivert 1357 // getcwd 1358 1359 @symbol("getcwd") fn libc_getcwd(buf: *u8, bufsz: size) *u8; 1360 1361 // The return value is statically allocated and must be duplicated before 1362 // calling getcwd again. 1363 export fn getcwd() (*const u8 | errno) = { 1364 static let pathbuf: [PATH_MAX]u8 = [0...]; 1365 1366 let res = libc_getcwd(&pathbuf: *u8, len(pathbuf)); 1367 if (res == null) { 1368 return *__errno(): errno; 1369 }; 1370 1371 return res; 1372 }; 1373 1374 // adjfreq 1375 // setrtable 1376 // getrtable 1377 // faccessat 1378 // fchmodat 1379 1380 @symbol("fchmodat") fn libc_fchmodat( 1381 fd: int, 1382 path: *const u8, 1383 mode: mode_t, 1384 flag: int 1385 ) int; 1386 1387 export fn fchmodat( 1388 dirfd: int, 1389 path: path, 1390 mode: mode_t, 1391 flag: int 1392 ) (void | errno) = { 1393 let res = libc_fchmodat(dirfd, cpath(path)?, mode, flag); 1394 if (res == -1) { 1395 return *__errno(): errno; 1396 }; 1397 }; 1398 1399 // fchownat 1400 1401 @symbol("fchownat") fn libc_fchownat( 1402 fd: int, 1403 path: *const u8, 1404 owner: uid_t, 1405 group: gid_t, 1406 flag: int 1407 ) int; 1408 1409 export fn fchownat( 1410 dirfd: int, 1411 path: path, 1412 uid: uid_t, 1413 gid: gid_t, 1414 flag: int 1415 ) (void | errno) = { 1416 let res = libc_fchownat(dirfd, cpath(path)?, uid, gid, flag); 1417 if (res == -1) { 1418 return *__errno(): errno; 1419 }; 1420 }; 1421 1422 // linkat 1423 1424 @symbol("linkat") fn libc_linkat( 1425 fd1: int, 1426 name1: *const u8, 1427 fd2: int, 1428 name2: *const u8, 1429 flag: int 1430 ) int; 1431 1432 export fn linkat( 1433 olddirfd: int, 1434 oldpath: path, 1435 newdirfd: int, 1436 newpath: path, 1437 flags: int, 1438 ) (void | errno) = { 1439 let oldpath = cpath(oldpath)?; 1440 let newpath = copy_cpath(newpath, pathbuf1)?; 1441 1442 let res = libc_linkat(olddirfd, oldpath, newdirfd, newpath, flags); 1443 if (res == -1) { 1444 return *__errno(): errno; 1445 }; 1446 }; 1447 1448 // mkdirat 1449 1450 @symbol("mkdirat") fn libc_mkdirat(fd: int, path: *const u8, mode: mode_t) int; 1451 1452 export fn mkdirat(dirfd: int, path: path, mode: mode_t) (void | errno) = { 1453 let res = libc_mkdirat(dirfd, cpath(path)?, mode); 1454 if (res == -1) { 1455 return *__errno(): errno; 1456 }; 1457 }; 1458 1459 // mkfifoat 1460 // mknodat 1461 1462 @symbol("mknodat") fn libc_mknodat( 1463 fd: int, 1464 path: *const u8, 1465 mode: mode_t, 1466 dev: dev_t 1467 ) int; 1468 1469 // The OpenBSD implementation of mknodat *only* supports FIFO and 1470 // device special files. 1471 export fn mknodat( 1472 dirfd: int, 1473 path: path, 1474 mode: mode_t, 1475 dev: dev_t, 1476 ) (void | errno) = { 1477 let res = libc_mknodat(dirfd, cpath(path)?, mode, dev); 1478 if (res == -1) { 1479 return *__errno(): errno; 1480 }; 1481 }; 1482 1483 // openat 1484 1485 @symbol("openat") fn libc_openat( 1486 fd: int, 1487 path: *const u8, 1488 flags: int, 1489 mode: uint, 1490 ) int; 1491 1492 export fn openat( 1493 dirfd: int, 1494 path: path, 1495 flags: int, 1496 mode: uint, 1497 ) (int | errno) = { 1498 let res = libc_openat(dirfd, cpath(path)?, flags, mode); 1499 if (res == -1) { 1500 return *__errno(): errno; 1501 }; 1502 return res; 1503 }; 1504 1505 // readlinkat 1506 1507 @symbol("readlinkat") fn libc_readlinkat( 1508 fd: int, 1509 path: *const u8, 1510 buf: *u8, 1511 bufsiz: size 1512 ) i64; 1513 1514 export fn readlinkat( 1515 dirfd: int, 1516 path: path, 1517 buf: []u8, 1518 ) (size | errno) = { 1519 let res = libc_readlinkat(dirfd, cpath(path)?, buf: *[*]u8: *u8, len(buf)); 1520 if (res == -1) { 1521 return *__errno(): errno; 1522 }; 1523 return res: size; 1524 }; 1525 1526 // renameat 1527 1528 @symbol("renameat") fn libc_renameat( 1529 fromfd: int, 1530 from: *const u8, 1531 tofd: int, 1532 to: *const u8 1533 ) int; 1534 1535 export fn renameat( 1536 olddirfd: int, 1537 oldpath: str, 1538 newdirfd: int, 1539 newpath: str, 1540 ) (void | errno) = { 1541 let newpath = copy_cpath(newpath, pathbuf1)?; 1542 1543 let res = libc_renameat(olddirfd, cpath(oldpath)?, newdirfd, 1544 newpath); 1545 if (res == -1) { 1546 return *__errno(): errno; 1547 }; 1548 }; 1549 1550 // symlinkat 1551 1552 @symbol("symlinkat") fn libc_symlinkat( 1553 name1: *const u8, 1554 fd: int, 1555 name2: *const u8 1556 ) int; 1557 1558 export fn symlinkat( 1559 target: path, 1560 newdirfd: int, 1561 linkpath: path, 1562 ) (void | errno) = { 1563 let target = cpath(target)?; 1564 let linkpath = copy_cpath(linkpath, pathbuf1)?; 1565 1566 let res = libc_symlinkat(target, newdirfd, linkpath); 1567 if (res == -1) { 1568 return *__errno(): errno; 1569 }; 1570 }; 1571 1572 // unlinkat 1573 1574 @symbol("unlinkat") fn libc_unlinkat(fd: int, path: *const u8, flag: int) int; 1575 1576 export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { 1577 let res = libc_unlinkat(dirfd, cpath(path)?, flags); 1578 if (res == -1) { 1579 return *__errno(): errno; 1580 }; 1581 }; 1582 1583 // __set_tcb 1584 // __get_tcb