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