Skip to content

Syscall API

The personality-aware syscall dispatcher and the kernel-ops callback table exposed to the Zig personality layer.

src/syscall_handler/time.rs

clock_gettime fn

rust
fn clock_gettime(clock : usize, buf : UserSliceWo) -> Result<()>

nanosleep fn

rust
fn nanosleep(req_buf : UserSliceRo, rem_buf_opt : Option<UserSliceWo>) -> Result<()>

Nanosleep will sleep by switching the current context

sched_yield fn

rust
fn sched_yield() -> Result<()>

src/syscall_handler/process.rs

exit_this_context fn

rust
fn exit_this_context(excp : Option<kernel_syscall::Exception>) ->!

mprotect fn

rust
fn mprotect(address : usize, size : usize, flags : MapFlags) -> Result<()>

usermode_bootstrap fn

rust
unsafe fn usermode_bootstrap(bootstrap : &Bootstrap)

bootstrap_mem fn

rust
unsafe fn bootstrap_mem(bootstrap : &crate::Bootstrap) -> &'static [u8]

src/syscall_handler/usercopy.rs

UserSlice struct

rust
struct UserSlice { /* … */ }

UserSliceRo type

rust
pub type UserSliceRo = UserSlice<true, false>;

UserSliceWo type

rust
pub type UserSliceWo = UserSlice<false, true>;

UserSliceRw type

rust
pub type UserSliceRw = UserSlice<true, true>;

UserSlice<READ, WRITE>::split_at fn

rust
fn split_at(self, idx : usize) -> Option<(Self, Self)>

Split [0, end) into [0, idx) and [idx, end)

UserSlice<READ, WRITE>::reinterpret_unchecked fn

rust
fn reinterpret_unchecked<const NEW_READ : bool, const NEW_WRITE : bool>(self,) -> UserSlice<NEW_READ, NEW_WRITE>

Not unsafe, because user memory is not covered by the memory model that decides if something is UB, but it can break logic invariants

validate_region fn

rust
fn validate_region(address : usize, size : usize) -> Result<PageSpan>

Convert [addr, addr+size) into (page, page_count).

This will fail if:

  • the base address is not page-aligned,
  • the length is not page-aligned,
  • the region is empty (EINVAL), or
  • any byte in the region exceeds USER_END_OFFSET (EFAULT).

src/syscall_handler/kernel_ops_table.rs

Kernel operation callback table for Zig personality layer

Convention: return i32 — non-negative = success value, negative = -errno. For M1 ("Hello World") only write and exit are wired.

open fn

rust
unsafe extern "C" fn open(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

close fn

rust
unsafe extern "C" fn close(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

read fn

rust
unsafe extern "C" fn read(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

write fn

rust
unsafe extern "C" fn write(fd : usize, buf : usize, count : usize, _d : usize, _e : usize, _f : usize) -> i32

lseek fn

rust
unsafe extern "C" fn lseek(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

fstat fn

rust
unsafe extern "C" fn fstat(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

fcntl fn

rust
unsafe extern "C" fn fcntl(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

dup fn

rust
unsafe extern "C" fn dup(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

dup2 fn

rust
unsafe extern "C" fn dup2(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

fpath fn

rust
unsafe extern "C" fn fpath(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

fsync fn

rust
unsafe extern "C" fn fsync(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

ftruncate fn

rust
unsafe extern "C" fn ftruncate(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

mkdir fn

rust
unsafe extern "C" fn mkdir(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

rmdir fn

rust
unsafe extern "C" fn rmdir(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32
rust
unsafe extern "C" fn unlink(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

rename fn

rust
unsafe extern "C" fn rename(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32
rust
unsafe extern "C" fn link(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32
rust
unsafe extern "C" fn symlink(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32
rust
unsafe extern "C" fn readlink(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

chmod fn

rust
unsafe extern "C" fn chmod(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

chown fn

rust
unsafe extern "C" fn chown(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

mmap fn

rust
unsafe extern "C" fn mmap(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

munmap fn

rust
unsafe extern "C" fn munmap(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

mprotect fn

rust
unsafe extern "C" fn mprotect(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

exit fn

rust
unsafe extern "C" fn exit(_code : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

getpid fn

rust
unsafe extern "C" fn getpid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

getppid fn

rust
unsafe extern "C" fn getppid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

getuid fn

rust
unsafe extern "C" fn getuid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

getgid fn

rust
unsafe extern "C" fn getgid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

geteuid fn

rust
unsafe extern "C" fn geteuid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

getegid fn

rust
unsafe extern "C" fn getegid(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

yield_op fn

rust
unsafe extern "C" fn yield_op(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

clock_gettime fn

rust
unsafe extern "C" fn clock_gettime(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

nanosleep fn

rust
unsafe extern "C" fn nanosleep(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

futex fn

rust
unsafe extern "C" fn futex(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

unimplemented fn

rust
unsafe extern "C" fn unimplemented(_a : usize, _b : usize, _c : usize, _d : usize, _e : usize, _f : usize) -> i32

Stub for reserved / unimplemented slots.

src/syscall_handler/debug.rs

format_call fn

rust
fn format_call(a : usize, b : usize, c : usize, d : usize, e : usize, f : usize) -> String

SyscallDebugInfo struct

rust
struct SyscallDebugInfo { /* … */ }

debug_start fn

rust
fn debug_start([a, b, c, d, e, f] : [usize; 6])

debug_end fn

rust
fn debug_end([a, b, c, d, e, f] : [usize; 6], result : Result<usize>)

src/syscall_handler/privilege.rs

mkns fn

rust
fn mkns(mut user_buf : UserSliceRo) -> Result<usize>

src/syscall_handler/fs.rs

Filesystem syscalls

file_op_generic fn

rust
fn file_op_generic<T>(fd : FileHandle, op : impl FnOnce(&dyn KernelScheme, usize) -> Result<T>,) -> Result<T>

file_op_generic_ext fn

rust
fn file_op_generic_ext<T>(fd : FileHandle, op : impl FnOnce(&dyn KernelScheme, Arc<RwLock<FileDescription>>, FileDescription) -> Result<T>,) -> Result<T>

copy_path_to_buf fn

rust
fn copy_path_to_buf(raw_path : UserSliceRo, max_len : usize) -> Result<alloc::string::String>

open fn

rust
fn open(raw_path : UserSliceRo, flags : usize) -> Result<FileHandle>

Open syscall

rmdir fn

rust
fn rmdir(raw_path : UserSliceRo) -> Result<()>

rmdir syscall

rust
fn unlink(raw_path : UserSliceRo) -> Result<()>

Unlink syscall

close fn

rust
fn close(fd : FileHandle) -> Result<()>

Close syscall

dup fn

rust
fn dup(fd : FileHandle, buf : UserSliceRo) -> Result<FileHandle>

Duplicate file descriptor

dup2 fn

rust
fn dup2(fd : FileHandle, new_fd : FileHandle, buf : UserSliceRo) -> Result<FileHandle>

Duplicate file descriptor, replacing another

call fn

rust
fn call(fd : FileHandle, payload : UserSliceRw, flags : CallFlags, metadata : UserSliceRo,) -> Result<usize>

sendfd fn

rust
fn sendfd(socket : FileHandle, fd : FileHandle, flags_raw : usize, arg : u64) -> Result<usize>

fcntl fn

rust
fn fcntl(fd : FileHandle, cmd : usize, arg : usize) -> Result<usize>

File descriptor controls

rust
fn flink(fd : FileHandle, raw_path : UserSliceRo) -> Result<()>

frename fn

rust
fn frename(fd : FileHandle, raw_path : UserSliceRo) -> Result<()>

fstat fn

rust
fn fstat(fd : FileHandle, user_buf : UserSliceWo) -> Result<()>

File status

funmap fn

rust
fn funmap(virtual_address : usize, length : usize) -> Result<usize>

mremap fn

rust
fn mremap(old_address : usize, old_size : usize, new_address : usize, new_size : usize, flags : usize,) -> Result<usize>

lseek fn

rust
fn lseek(fd : FileHandle, pos : i64, whence : usize) -> Result<usize>

sys_read fn

rust
fn sys_read(fd : FileHandle, buf : UserSliceWo) -> Result<usize>

sys_write fn

rust
fn sys_write(fd : FileHandle, buf : UserSliceRo) -> Result<usize>

src/syscall_handler/futex.rs

Futex

Futex or Fast Userspace Mutex is "a method for waiting until a certain condition becomes true."

For more information about futexes, please read this blog post, and the futex(2) man page

FutexEntry struct

rust
struct FutexEntry { /* … */ }

futex fn

rust
fn futex(addr : usize, op : usize, val : usize, val2 : usize, _addr2 : usize) -> Result<usize>

src/syscall_handler/mod.rs

Multi-personality syscall handler

This module replaces the old single-dispatch syscall handler with a personality-aware dispatcher. It calls into the Zig personality library to handle syscall dispatch per OS personality.

Personality enum

rust
enum Personality {
    Kernel = 0,
    Linux = 1,
    Windows = 2,
    Darwin = 3,
    FreeBSD = 4,
    NetBSD = 5,
    OpenBSD = 6,
}

Personality identifiers, matching personality/src/personality.zig.

KernelOp type

rust
pub type KernelOp = unsafe extern "C" fn(a : usize, b : usize, c : usize, d : usize, e : usize, f : usize,) -> i32;

KernelOps struct

rust
struct KernelOps { /* … */ }

init_personality fn

rust
fn init_personality()

Initialise the personality layer. Leaks the ops table for permanent lifetime.

syscall fn

rust
fn syscall(a : usize, b : usize, c : usize, d : usize, e : usize, f : usize) -> usize

The main syscall entry point, called from arch trap handlers.

Released under the AWFixer Source Available License v0.4. #linuswasright