libgbsd - System Library Reference


libgbsd is the official userland system library for GuardBSD.

It provides safe, high-level Rust wrappers over the raw syscall interface exposed by the three microkernels-µK-Space, µK-Time, and µK-IPC.

The library includes:

  • filesystem operations,
  • process control,
  • memory mapping,
  • directory utilities,
  • threading abstractions,
  • IPC helpers,
  • basic networking interfaces.

This documentation reflects GuardBSD 1.0.0 (Winter Saga).


Filesystem API

The filesystem interface is implemented by user-space servers (VFS/GuardFS), while libgbsd exposes safe wrappers.

Derived from the Complete API Reference and Examples (refs 3 and 4).

Opening, Reading & Writing Files


let fd = open("/tmp/data.txt", O_RDWR | O_CREAT)?;
write(fd, b"Hello, GuardBSD!")?;
let mut buf = [0u8; 64];
let n = read(fd, &mut buf)?;
close(fd)?;

File Operations


pub fn open(path: &str, flags: OpenFlags) -> Result<Fd>;
pub fn close(fd: Fd) -> Result<()>;
pub fn read(fd: Fd, buf: &mut [u8]) -> Result<usize>;
pub fn write(fd: Fd, buf: &[u8]) -> Result<usize>;
pub fn seek(fd: Fd, offset: i64, whence: SeekWhence) -> Result<u64>;

Metadata


pub fn stat(path: &str) -> Result<Stat>;
pub fn chmod(path: &str, mode: u32) -> Result<()>;

Directory API


pub fn mkdir(path: &str, mode: u32) -> Result<()>;
pub fn rmdir(path: &str) -> Result<()>;
pub fn readdir(path: &str) -> Result<Vec<DirEntry>>;

File Deletion

pub fn unlink(path: &str) -> Result<()>;

All file operations rely on the capability-secured VFS server.


Process API

Processes are created and controlled using libgbsd wrappers that manage low-level µK-Time and µK-IPC coordination.

Reference:

Process Lifecycle


pub fn fork() -> Result<Pid>;
pub fn exec(path: &str, args: &[&str]) -> Result<!>;
pub fn wait(pid: Pid) -> Result<i32>;
pub fn exit(code: i32) -> !;

Process Info


pub fn getpid() -> Pid;
pub fn getppid() -> Pid;
pub fn getuid() -> Uid;
pub fn setuid(uid: Uid) -> Result<()>;

exec() replaces the current process image and never returns.


Memory API

Userland memory is controlled via µK-Space through safe abstractions:

Mapping Memory


let ptr = mmap(
    std::ptr::null_mut(),
    4096,
    Prot::READ | Prot::WRITE,
    MapFlags::PRIVATE | MapFlags::ANONYMOUS
)?;

API Overview


pub fn mmap(addr: *mut u8, len: usize, prot: Prot, flags: MapFlags) -> Result<*mut u8>;
pub fn munmap(addr: *mut u8, len: usize) -> Result<()>;
pub fn mprotect(addr: *mut u8, len: usize, prot: Prot) -> Result<()>;

Shared Memory (Future-compatible)


pub fn shmget(key: i32, size: usize, flags: i32) -> Result<i32>;
pub fn shmat(shmid: i32, addr: *const u8, flags: i32) -> Result<*mut u8>;
pub fn shmdt(addr: *const u8) -> Result<()>;

Large IPC payloads should use shared memory for zero-copy communication.


Threading & Concurrency

Userland exposes high-level thread helpers powered by µK-Time.

Creating Threads


let tid = thread_create(worker_thread, stack)?;
let code = thread_join(tid)?;

API


pub fn thread_create(entry: fn() -> i32, stack: *mut u8) -> Result<Tid>;
pub fn thread_join(tid: Tid) -> Result<i32>;
pub fn thread_yield();

Example from documentation:


fn worker_thread() -> i32 {
    println!("Worker running");
    42
}


IPC Helpers

These wrappers simplify communication with µK-IPC using ports and messages.

Based on IPC protocol:

Sending & Receiving


let port = port_create()?;
ipc_send(port, &Message::new(1, b"Hello"))?;
let msg = ipc_receive(port)?;

Synchronous RPC

let reply = ipc_call(server_port, &req)?;

High-level patterns supported by libgbsd:

  • request/response RPC
  • async messaging
  • notification channels
  • capability delegation across processes

ipc_call() automatically creates a temporary reply port and handles cleanup.


Networking (via netd)

Networking in GuardBSD is implemented fully in user-space via the netd server. libgbsd exposes socket-style wrappers.

From API reference:

Socket API


pub fn socket(domain: Domain, type_: SocketType, protocol: Protocol) -> Result<Socket>;
pub fn bind(sock: Socket, addr: &SocketAddr) -> Result<()>;
pub fn listen(sock: Socket, backlog: i32) -> Result<()>;
pub fn accept(sock: Socket) -> Result<(Socket, SocketAddr)>;
pub fn connect(sock: Socket, addr: &SocketAddr) -> Result<()>;

Send/Receive


pub fn send(sock: Socket, buf: &[u8], flags: SendFlags) -> Result<usize>;
pub fn recv(sock: Socket, buf: &mut [u8], flags: RecvFlags) -> Result<usize>;

Example (UDP):


let sock = socket(AF_INET, SOCK_DGRAM, 0)?;
sendto(sock, b"ping", &addr)?;
let (n, sender) = recvfrom(sock, &mut buf)?;


Error Model

All libgbsd functions return:

pub type Result<T> = core::result::Result<T, Error>;

Errors cover:

  • invalid argument
  • permission denied
  • out-of-memory
  • resource exhausted
  • timeout
  • capability revoked

libgbsd transparently maps raw kernel -errno values into typed Error.


Related Documentation

  • Syscalls - low-level interface
  • ABI - binary structure layouts
  • CLI - userland tooling