syscalls.ha (19939B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 export fn syscall(num: u64, args: u64...) u64 = { 5 switch (len(args)) { 6 case 0 => return syscall0(num); 7 case 1 => return syscall1(num, args[0]); 8 case 2 => return syscall2(num, args[0], args[1]); 9 case 3 => return syscall3(num, args[0], args[1], args[2]); 10 case 4 => return syscall4(num, args[0], args[1], args[2], args[3]); 11 case 5 => return syscall5(num, args[0], args[1], args[2], args[3], args[4]); 12 case 6 => return syscall6(num, args[0], args[1], args[2], args[3], args[4], args[5]); 13 case => abort("syscalls can't have more than 6 arguments"); 14 }; 15 }; 16 17 fn syscall0(u64) u64; 18 fn syscall1(u64, u64) u64; 19 fn syscall2(u64, u64, u64) u64; 20 fn syscall3(u64, u64, u64, u64) u64; 21 fn syscall4(u64, u64, u64, u64, u64) u64; 22 fn syscall5(u64, u64, u64, u64, u64, u64) u64; 23 fn syscall6(u64, u64, u64, u64, u64, u64, u64) u64; 24 25 export def NAME_MAX: size = 255z; 26 export def PATH_MAX: size = 1024z; 27 export type path = (str | []u8 | *const u8); 28 let pathbuf: [PATH_MAX]u8 = [0...]; 29 30 fn copy_kpath(path: path, buf: []u8) (*const u8 | errno) = { 31 let path = match (path) { 32 case let c: *const u8 => 33 return c; 34 case let s: str => 35 let ptr = &s: *struct { 36 buf: *[*]u8, 37 length: size, 38 capacity: size, 39 }; 40 yield ptr.buf[..ptr.length]; 41 case let b: []u8 => 42 yield b; 43 }; 44 if (len(path) + 1 >= len(pathbuf)) { 45 return ENAMETOOLONG; 46 }; 47 memcpy(buf: *[*]u8, path: *[*]u8, len(path)); 48 buf[len(path)] = 0; 49 return buf: *[*]u8: *const u8; 50 }; 51 52 // NUL terminates a string and stores it in a static buffer of PATH_MAX bytes in 53 // length. 54 fn kpath(path: path) (*const u8 | errno) = { 55 return copy_kpath(path, pathbuf); 56 }; 57 58 export fn read(fd: int, buf: *opaque, count: size) (size | errno) = { 59 return wrap_return(syscall3(SYS_read, 60 fd: u64, buf: uintptr: u64, count: u64))?: size; 61 }; 62 63 export fn write(fd: int, buf: *const opaque, count: size) (size | errno) = { 64 return wrap_return(syscall3(SYS_write, 65 fd: u64, buf: uintptr: u64, count: u64))?: size; 66 }; 67 68 export fn readv(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 69 return wrap_return(syscall3(SYS_readv, 70 fd: u64, iov: uintptr: u64, iovcnt: u64))?: size; 71 }; 72 73 export fn writev(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { 74 return wrap_return(syscall3(SYS_writev, 75 fd: u64, iov: uintptr: u64, iovcnt: u64))?: size; 76 }; 77 78 export fn close(fd: int) (void | errno) = { 79 wrap_return(syscall1(SYS_close, fd: u64))?; 80 }; 81 82 export fn lseek(fd: int, off: i64, whence: int) (i64 | errno) = { 83 return wrap_return(syscall3(SYS_lseek, 84 fd: u64, off: u64, whence: u64))?: i64; 85 }; 86 87 export fn ftruncate(fd: int, ln: off_t) (void | errno) = { 88 wrap_return(syscall2(SYS_ftruncate, fd: u64, ln: u32))?; 89 }; 90 91 export fn pipe2(pipefd: *[2]int, flags: int) (void | errno) = { 92 wrap_return(syscall2(SYS_pipe2, pipefd: uintptr: u64, flags: u64))?; 93 }; 94 95 export type ioctl_arg = (nullable *opaque | u64); 96 97 export fn ioctl(fd: int, req: u64, arg: ioctl_arg) (int | errno) = { 98 let fd = fd: u64, req = req: u64; 99 return wrap_return(match (arg) { 100 case let u: u64 => 101 yield syscall3(SYS_ioctl, fd, req, u); 102 case let v: nullable *opaque => 103 yield syscall3(SYS_ioctl, fd, req, v: uintptr: u64); 104 })?: int; 105 }; 106 107 export fn openat( 108 dirfd: int, 109 path: path, 110 flags: int, 111 mode: uint, 112 ) (int | errno) = { 113 let path = kpath(path)?; 114 return wrap_return(syscall4(SYS_openat, dirfd: u64, 115 path: uintptr: u64, flags: u64, mode: u64))?: int; 116 }; 117 118 export fn open(path: str, flags: int, mode: uint) (int | errno) = { 119 return openat(AT_FDCWD, path, flags, mode); 120 }; 121 122 export fn unlink(path: path) (void | errno) = { 123 let path = kpath(path)?; 124 wrap_return(syscall3(SYS_unlinkat, 125 AT_FDCWD: u64, path: uintptr: u64, 0u64))?; 126 }; 127 128 export fn renameat( 129 olddirfd: int, 130 oldpath: str, 131 newdirfd: int, 132 newpath: str, 133 ) (void | errno) = { 134 let oldpath = kpath(oldpath)?; 135 static let newpathbuf: [PATH_MAX]u8 = [0...]; 136 let newpath = copy_kpath(newpath, newpathbuf)?; 137 wrap_return(syscall4(SYS_renameat, 138 olddirfd: u64, oldpath: uintptr: u64, 139 newdirfd: u64, newpath: uintptr: u64))?; 140 }; 141 142 export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { 143 let path = kpath(path)?; 144 wrap_return(syscall3(SYS_unlinkat, 145 dirfd: u64, path: uintptr: u64, flags: u64))?; 146 }; 147 148 export fn fstatat(fd: int, path: path, stat: *st, flag: int) (void | errno) = { 149 let path = kpath(path)?; 150 let fbstat = freebsd11_stat { ... }; 151 wrap_return(syscall4(SYS_freebsd11_fstatat, fd: u64, 152 path: uintptr: u64, &fbstat: uintptr: u64, flag: u64))?; 153 stat.dev = fbstat.st_dev; 154 stat.ino = fbstat.st_ino; 155 stat.mode = fbstat.st_mode; 156 stat.nlink = fbstat.st_nlink; 157 stat.uid = fbstat.st_uid; 158 stat.gid = fbstat.st_gid; 159 stat.rdev = fbstat.st_rdev; 160 stat.atime.tv_sec = fbstat.st_atim.tv_sec; 161 stat.atime.tv_nsec = fbstat.st_atim.tv_nsec: i64; 162 stat.mtime.tv_sec = fbstat.st_mtim.tv_sec; 163 stat.mtime.tv_nsec = fbstat.st_mtim.tv_nsec: i64; 164 stat.ctime.tv_sec = fbstat.st_ctim.tv_sec; 165 stat.ctime.tv_nsec = fbstat.st_ctim.tv_nsec: i64; 166 stat.btime.tv_sec = fbstat.st_birthtim.tv_sec; 167 stat.btime.tv_nsec = fbstat.st_birthtim.tv_nsec: i64; 168 stat.sz = fbstat.st_size; 169 stat.blocks = fbstat.st_blocks; 170 stat.blksz = fbstat.st_blksize; 171 stat.flags = fbstat.st_flags; 172 }; 173 174 export fn fstat(fd: int, stat: *st) (errno | void) = 175 fstatat(fd, "", stat, AT_EMPTY_PATH); 176 177 export fn readlinkat( 178 dirfd: int, 179 path: path, 180 buf: []u8, 181 ) (size | errno) = { 182 let path = kpath(path)?; 183 return wrap_return(syscall4(SYS_readlinkat, 184 dirfd: u64, path: uintptr: u64, 185 buf: *[*]u8: uintptr: u64, 186 len(buf): u64))?: size; 187 }; 188 189 export fn mkdirat(dirfd: int, path: path, mode: uint) (void | errno) = { 190 let path = kpath(path)?; 191 wrap_return(syscall3(SYS_mkdirat, 192 dirfd: u64, path: uintptr: u64, mode: u64))?; 193 }; 194 195 196 export fn fchmod(fd: int, mode: uint) (void | errno) = { 197 wrap_return(syscall2(SYS_fchmod, 198 fd: u64, mode: u64))?; 199 }; 200 201 export fn fchmodat(dirfd: int, path: path, mode: uint, flags: int) (void | errno) = { 202 let path = kpath(path)?; 203 wrap_return(syscall4(SYS_fchmodat, 204 dirfd: u64, path: uintptr: u64, mode: u64, flags: u64))?; 205 }; 206 207 export fn fchown(fd: int, uid: uint, gid: uint) (void | errno) = { 208 wrap_return(syscall3(SYS_fchown, 209 fd: u64, uid: u32, gid: u32))?; 210 }; 211 212 export fn fchownat(dirfd: int, path: path, uid: uint, gid: uint, flags: int) (void | errno) = { 213 let path = kpath(path)?; 214 wrap_return(syscall5(SYS_fchownat, 215 dirfd: u64, path: uintptr: u64, uid: u32, gid: u32, flags: u64))?; 216 }; 217 218 export fn utimensat(dirfd: int, path: str, ts: *[2]timespec, flags: int) (void | errno) = { 219 let path = kpath(path)?; 220 wrap_return(syscall4(SYS_utimensat, 221 dirfd: u64, path: uintptr: u64, ts: uintptr: u64, flags: u64))?; 222 }; 223 224 export fn futimens(fd: int, ts: *[2]timespec) (void | errno) = { 225 wrap_return(syscall2(SYS_futimens, 226 fd: u64, ts: uintptr: u64))?; 227 }; 228 229 export fn faccessat( 230 dirfd: int, 231 path: path, 232 mode: int, 233 flags: int, 234 ) (bool | errno) = { 235 let path = kpath(path)?; 236 match (wrap_return(syscall4(SYS_faccessat, dirfd: u64, 237 path: uintptr: u64, mode: u64, flags: u64))) { 238 case let err: errno => 239 switch (err) { 240 case EACCES => 241 return false; 242 case => 243 return err; 244 }; 245 case let n: u64 => 246 assert(n == 0); 247 return true; 248 }; 249 }; 250 251 // The use of this function is discouraged, as it can create race conditions. 252 // TOCTOU is preferred: attempt to simply use the resource you need and handle 253 // any access errors which occur. 254 export fn access(path: path, mode: int) (bool | errno) = 255 faccessat(AT_FDCWD, path, mode, 0); 256 257 // TODO: Consider updating this to use SYS_freebsd11_getdirentries 258 export fn getdents(dirfd: int, buf: *opaque, nbytes: size) (size | errno) = { 259 return wrap_return(syscall3(SYS_freebsd11_getdents, dirfd: u64, 260 buf: uintptr: u64, nbytes: u64))?: size; 261 }; 262 263 // The return value is statically allocated and must be duplicated before 264 // calling getcwd again. 265 export fn getcwd() (*const u8 | errno) = { 266 static let pathbuf: [PATH_MAX]u8 = [0...]; 267 wrap_return(syscall2(SYS___getcwd, 268 &pathbuf: *[*]u8: uintptr: u64, 269 PATH_MAX))?; 270 return &pathbuf: *const u8; 271 }; 272 273 export fn fchdir(fd: int) (void | errno) = { 274 wrap_return(syscall1(SYS_fchdir, fd: u64))?; 275 }; 276 277 export fn chdir(path: path) (void | errno) = { 278 let path = kpath(path)?; 279 wrap_return(syscall1(SYS_chdir, path: uintptr: u64))?; 280 }; 281 282 export fn chroot(path: path) (void | errno) = { 283 let path = kpath(path)?; 284 wrap_return(syscall1(SYS_chroot, path: uintptr: u64))?; 285 }; 286 287 export fn mmap( 288 addr: nullable *opaque, 289 length: size, 290 prot: uint, 291 flags: uint, 292 fd: int, 293 offs: size 294 ) (errno | *opaque) = { 295 return wrap_return(syscall6(SYS_mmap, addr: uintptr: u64, 296 length: u64, prot: u64, flags: u64, 297 fd: u64, offs: u64))?: uintptr: *opaque; 298 }; 299 300 export fn munmap(addr: *opaque, length: size) (void | errno) = { 301 wrap_return(syscall2(SYS_munmap, addr: uintptr: u64, length: u64))?; 302 }; 303 304 export fn exit(status: int) never = { 305 syscall1(SYS_exit, status: u64); 306 abort(); 307 }; 308 309 export fn kill(pid: pid_t, signal: int) (void | errno) = { 310 wrap_return(syscall2(SYS_kill, pid: u64, signal: u64))?; 311 }; 312 313 export fn fork() (pid_t | void | errno) = { 314 let n = wrap_return(syscall0(SYS_fork))?: pid_t; 315 switch (n) { 316 case 0 => 317 return; 318 case => 319 return n; 320 }; 321 }; 322 323 export fn fexecve(fd: int, argv: *[*]nullable *const u8, 324 envp: *[*]nullable *const u8) errno = { 325 return match (wrap_return(syscall3(SYS_fexecve, fd: u64, 326 argv: uintptr: u64, envp: uintptr: u64))) { 327 case let err: errno => 328 yield err; 329 case u64 => 330 abort("unreachable"); 331 }; 332 }; 333 334 export fn wait4( 335 pid: pid_t, 336 wstatus: nullable *int, 337 options: int, 338 rusage: nullable *rusage, 339 ) (int | errno) = { 340 return wrap_return(syscall4(SYS_wait4, 341 pid: u64, wstatus: uintptr: u64, 342 options: u64, rusage: uintptr: u64))?: int; 343 }; 344 345 export fn wifexited(status: int) bool = wtermsig(status) == 0; 346 export fn wexitstatus(status: int) int = (status & 0xff00) >> 8; 347 348 export fn wtermsig(status: int) int = status & 0x7f; 349 export fn wifsignaled(status: int) bool = 350 wtermsig(status) != 0o177 && wtermsig(status) != 0 && status != 0x13; 351 352 export fn getpid() pid_t = syscall0(SYS_getpid): pid_t; 353 354 export fn getppid() pid_t = syscall0(SYS_getppid): pid_t; 355 356 export fn getpgrp() pid_t = syscall0(SYS_getpgrp): pid_t; 357 358 export fn getpgid(pid: pid_t) (pid_t | errno) = { 359 return wrap_return(syscall1(SYS_getpgid, pid))?: pid_t; 360 }; 361 362 export fn getsid(pid: pid_t) (pid_t | errno) = { 363 return wrap_return(syscall1(SYS_getsid, pid))?: pid_t; 364 }; 365 366 export fn getpriority(which: int, who: id_t) (int | errno) = { 367 return wrap_return(syscall2(SYS_getpriority, 368 which: u64, who: u64))?: int; 369 }; 370 371 export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = { 372 wrap_return(syscall3(SYS_setpriority, which: u64, who: u64, prio: u64))?; 373 }; 374 375 export fn umask(mode: mode_t) (mode_t | errno) = { 376 return wrap_return(syscall1(SYS_umask, mode: u64))?: mode_t; 377 }; 378 379 export fn setresuid(uid: uid_t, euid: uid_t, suid: uid_t) (void | errno) = { 380 wrap_return(syscall3(SYS_setresuid, uid: u64, euid: u64, suid: u64))?; 381 }; 382 383 export fn setresgid(gid: gid_t, egid: gid_t, sgid: gid_t) (void | errno) = { 384 wrap_return(syscall3(SYS_setresgid, gid: u64, egid: u64, sgid: u64))?; 385 }; 386 387 export fn getgroups(gids: []gid_t) (uint | errno) = { 388 return wrap_return(syscall2(SYS_getgroups, 389 len(gids): u64, gids: *[*]gid_t: uintptr: u64))?: uint; 390 }; 391 392 export fn setgroups(gids: []gid_t) (void | errno) = { 393 wrap_return(syscall2(SYS_setgroups, 394 len(gids): u64, gids: *[*]gid_t: uintptr: u64))?; 395 }; 396 397 export fn getresuid(uid: *uid_t, euid: *uid_t, suid: *uid_t) (void | errno) = { 398 wrap_return(syscall3(SYS_getresuid, 399 uid: uintptr: u64, 400 euid: uintptr: u64, 401 suid: uintptr: u64))?; 402 }; 403 404 export fn getresgid(gid: *gid_t, egid: *gid_t, sgid: *gid_t) (void | errno) = { 405 wrap_return(syscall3(SYS_getresgid, 406 gid: uintptr: u64, 407 egid: uintptr: u64, 408 sgid: uintptr: u64))?; 409 }; 410 411 export fn clock_gettime(clock_id: int, tp: *timespec) (void | errno) = { 412 wrap_return(syscall2(SYS_clock_gettime, 413 clock_id: u64, tp: uintptr: u64))?; 414 }; 415 416 export fn clock_settime(clock_id: int, tp: *const timespec) (void | errno) = { 417 wrap_return(syscall2(SYS_clock_settime, 418 clock_id: u64, tp: uintptr: u64))?; 419 }; 420 421 export fn nanosleep(req: *const timespec, rem: *timespec) (void | errno) = { 422 wrap_return(syscall2(SYS_nanosleep, 423 req: uintptr: u64, rem: uintptr: u64))?; 424 }; 425 426 export fn getrandom(buf: *opaque, bufln: size, flags: uint) (size | errno) = { 427 return wrap_return(syscall3(SYS_getrandom, 428 buf: uintptr: u64, bufln: u64, flags: u64))?: size; 429 }; 430 431 export type fcntl_arg = (void | int | *st_flock | *u64); 432 433 export fn fcntl(fd: int, cmd: int, arg: fcntl_arg) (int | errno) = { 434 let _fd = fd: u64, _cmd = cmd: u64; 435 return wrap_return(match (arg) { 436 case void => 437 yield syscall2(SYS_fcntl, _fd, _cmd); 438 case let i: int => 439 yield syscall3(SYS_fcntl, _fd, _cmd, i: u64); 440 case let l: *st_flock => 441 yield syscall3(SYS_fcntl, _fd, _cmd, l: uintptr: u64); 442 case let u: *u64 => 443 yield syscall3(SYS_fcntl, _fd, _cmd, u: uintptr: u64); 444 })?: int; 445 }; 446 447 export fn ppoll( 448 fds: *[*]pollfd, 449 nfds: nfds_t, 450 timeout: const nullable *timespec, 451 sigmask: const nullable *sigset, 452 ) (int | errno) = { 453 return wrap_return(syscall4(SYS_ppoll, fds: uintptr: u64, nfds: u64, 454 timeout: uintptr: u64, sigmask: uintptr: u64))?: int; 455 }; 456 457 export fn poll(fds: *[*]pollfd, nfds: nfds_t, timeout: int) (int | errno) = { 458 const ts = timespec { 459 tv_sec = timeout % 1000, 460 tv_nsec = timeout * 1000000, 461 }; 462 return ppoll(fds, nfds, (if (timeout != -1) &ts else null), null); 463 }; 464 465 export fn socket(domain: int, type_: int, protocol: int) (int | errno) = { 466 return wrap_return(syscall3(SYS_socket, 467 domain: u64, type_: u64, protocol: u64))?: int; 468 }; 469 470 export fn socketpair( 471 domain: int, 472 type_: int, 473 protocol: int, 474 sv: *[*]int, 475 ) (int | errno) = { 476 return wrap_return(syscall4(SYS_socketpair, domain: u64, 477 type_: u64, protocol: u64, sv: uintptr : u64))?: int; 478 }; 479 480 export fn connect(sockfd: int, addr: *const sockaddr, addrlen: u32) (int | errno) = { 481 return wrap_return(syscall3(SYS_connect, 482 sockfd: u64, addr: uintptr: u64, addrlen: u64))?: int; 483 }; 484 485 export fn bind(sockfd: int, addr: *const sockaddr, addrlen: u32) (int | errno) = { 486 return wrap_return(syscall3(SYS_bind, 487 sockfd: u64, addr: uintptr: u64, addrlen: u64))?: int; 488 }; 489 490 export fn listen(sockfd: int, backlog: u32) (int | errno) = { 491 return wrap_return(syscall2(SYS_listen, 492 sockfd: u64, backlog: u64))?: int; 493 }; 494 495 export fn accept(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { 496 return wrap_return(syscall3(SYS_accept, 497 sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; 498 }; 499 500 export fn accept4(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32, flags: int) (int | errno) = { 501 return wrap_return(syscall4(SYS_accept4, 502 sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64, flags: u64))?: int; 503 }; 504 505 export fn recvfrom(sockfd: int, buf: *opaque, len_: size, flags: int, 506 src_addr: nullable *sockaddr, addrlen: nullable *u32 507 ) (size | errno) = { 508 return wrap_return(syscall6(SYS_recvfrom, 509 sockfd: u64, buf: uintptr: u64, len_: u64, flags: u64, 510 src_addr: uintptr: u64, addrlen: uintptr: u64))?: size; 511 }; 512 513 export fn sendto(sockfd: int, buf: *opaque, len_: size, flags: int, 514 dest_addr: nullable *sockaddr, addrlen: u32 515 ) (size | errno) = { 516 return wrap_return(syscall6(SYS_sendto, 517 sockfd: u64, buf: uintptr: u64, len_: u64, flags: u64, 518 dest_addr: uintptr: u64, addrlen: u64))?: size; 519 }; 520 521 export fn recv(sockfd: int, buf: *opaque, len_: size, flags: int) (size | errno) = { 522 return recvfrom(sockfd, buf, len_, flags, null, null); 523 }; 524 525 export fn send(sockfd: int, buf: *opaque, len_: size, flags: int) (size | errno) = { 526 return sendto(sockfd, buf, len_, flags, null, 0); 527 }; 528 529 export fn sendmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { 530 return wrap_return(syscall3(SYS_sendmsg, 531 fd: u64, msg: uintptr: u64, flags: u64))?: int; 532 }; 533 534 export fn recvmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { 535 return wrap_return(syscall3(SYS_recvmsg, 536 fd: u64, msg: uintptr: u64, flags: u64))?: int; 537 }; 538 539 export fn getsockopt(sockfd: int, level: int, optname: int, optval: nullable *opaque, optlen: nullable *u32) (int | errno) = { 540 return wrap_return(syscall5(SYS_getsockopt, 541 sockfd: u64, level: u64, optname: u64, 542 optval: uintptr: u64, optlen: uintptr: u64))?: int; 543 }; 544 545 export fn setsockopt(sockfd: int, level: int, optname: int, optval: *opaque, optlen: u32) (int | errno) = { 546 return wrap_return(syscall5(SYS_setsockopt, 547 sockfd: u64, level: u64, optname: u64, 548 optval: uintptr: u64, optlen: u64))?: int; 549 }; 550 551 export fn getsockname(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { 552 return wrap_return(syscall3(SYS_getsockname, 553 sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; 554 }; 555 556 export fn getpeername(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { 557 return wrap_return(syscall3(SYS_getpeername, 558 sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; 559 }; 560 561 export fn sysctlbyname(name: str, oldp: nullable *opaque, oldlenp: nullable *size, 562 newp: nullable *const opaque, newlen: size) (void | errno) = { 563 let kname = kpath(name)?; 564 wrap_return(syscall6(SYS___sysctlbyname, 565 kname: uintptr: u64, len(name): u64, 566 oldp: uintptr: u64, oldlenp: uintptr: u64, 567 newp: uintptr: u64, newlen: u64))?; 568 }; 569 570 export fn dup2(oldfd: int, newfd: int) (int | errno) = { 571 return wrap_return(syscall2(SYS_dup2, oldfd: u64, newfd: u64))?: int; 572 }; 573 574 export fn posix_openpt(flags: int) (int | errno) = { 575 return wrap_return(syscall1(SYS_posix_openpt, flags: u64))?: int; 576 }; 577 578 export fn posix_fallocate(fd: int, off: i64, ln: i64) (void | errno) = { 579 wrap_return(syscall3(SYS_posix_fallocate, 580 fd: u64, off: u64, ln: u64))?; 581 }; 582 583 export fn flock(fd: int, op: int) (void | errno) = { 584 wrap_return(syscall2(SYS_flock, 585 fd: u64, op: u64))?; 586 }; 587 588 export fn shm_open( 589 shm_path: path, 590 oflags: int, 591 mode: mode_t, 592 shmflags: int, 593 anon_path: path, 594 ) (int | errno) = { 595 const shm_path = match (shm_path) { 596 case let string: *const u8 => 597 if (string == SHM_ANON) yield SHM_ANON; 598 yield kpath(shm_path)?; 599 case => 600 yield kpath(shm_path)?; 601 }; 602 const anon_path = kpath(anon_path)?; 603 return wrap_return(syscall5(SYS_shm_open2, 604 shm_path: uintptr: u64, 605 oflags: u64, 606 mode: u64, 607 shmflags: u64, 608 anon_path: uintptr: u64))?: int; 609 }; 610 611 export fn shm_unlink(shm_path: path) (void | errno) = { 612 const path = kpath(shm_path)?; 613 wrap_return(syscall1(SYS_shm_unlink, path: uintptr: u64))?; 614 }; 615 616 export fn shmat(id: int, addr: *const opaque, flag: int) *opaque = { 617 return syscall3(SYS_shmat, id: u64, addr: uintptr: u64, 618 flag: u64): uintptr: *opaque; 619 }; 620 621 export fn getrlimit(resource: int, rlim: *rlimit) (void | errno) = { 622 wrap_return(syscall2(SYS_getrlimit, 623 resource: u64, rlim: uintptr: u64))?; 624 }; 625 626 export fn setrlimit(resource: int, rlim: *const rlimit) (void | errno) = { 627 wrap_return(syscall2(SYS_setrlimit, 628 resource: u64, rlim: uintptr: u64))?; 629 }; 630 631 export fn sigprocmask( 632 how: int, 633 set: nullable *const sigset, 634 old: nullable *sigset, 635 ) (int | errno) = { 636 return wrap_return(syscall3(SYS_sigprocmask, 637 how: u64, set: uintptr: u64, old: uintptr: u64))?: int; 638 }; 639 640 export fn sigaction( 641 signum: int, 642 act: *const sigact, 643 old: nullable *sigact, 644 ) (int | errno) = { 645 return wrap_return(syscall3(SYS_sigaction, 646 signum: u64, act: uintptr: u64, old: uintptr: u64))?: int; 647 }; 648 649 export fn sigaltstack( 650 ss: nullable *stack_t, 651 old_ss: nullable *stack_t, 652 ) (void | errno) = { 653 wrap_return(syscall2(SYS_sigaltstack, 654 ss: uintptr: u64, old_ss: uintptr: u64))?; 655 }; 656 657 export fn shutdown(sockfd: int, how: int) (void | errno) = { 658 wrap_return(syscall2(SYS_shutdown, 659 sockfd: u64, how: u64))?; 660 }; 661 662 export fn fsync(fd: int) (void | errno) = { 663 wrap_return(syscall1(SYS_fsync, fd: u64))?; 664 }; 665 666 export fn fdatasync(fd: int) (void | errno) = { 667 wrap_return(syscall1(SYS_fdatasync, fd: u64))?; 668 };