fs

Minimal file I/O via direct Linux syscalls. No libc dependency. Each internal helper function contains at most one syscall to avoid register corruption in the current compiler.

For higher-level convenience functions, see file_io.

Usage

import fs

fn main() {
    // Write a file
    let data = "Hello from Jda!\n"
    fs_write_file("/tmp/hello.txt", data, 16)

    // Check existence
    if fs_exists("/tmp/hello.txt") == 1 {
        print(1)   // file exists
    }

    // Read it back
    let buf: &i8 = alloc_pages(1)
    let n = fs_read_file("/tmp/hello.txt", buf, 4096)
    print(n)   // 16

    // Get file size
    let size = fs_file_size("/tmp/hello.txt")
    print(size)   // 16

    // Create a directory
    fs_mkdir("/tmp/jda_test")

    // Clean up
    fs_unlink("/tmp/hello.txt")
}

Function Reference

FunctionSignatureDescription
fs_read_file(path: &i8, buf: &i8, max_bytes: i64) -> i64Read file into buffer
fs_write_file(path: &i8, data: &i8, len: i64) -> i64Write data to file (create/truncate)
fs_append_file(path: &i8, data: &i8, len: i64) -> i64Append data to file
fs_exists(path: &i8) -> i64Check if file exists
fs_unlink(path: &i8) -> i64Delete a file
fs_mkdir(path: &i8) -> i64Create a directory (mode 0755)
fs_file_size(path: &i8) -> i64Get file size in bytes

Detailed API

fs_read_file

fn fs_read_file(path: &i8, buf: &i8, max_bytes: i64) -> i64

Read up to max_bytes from a file into the provided buffer. Opens the file, reads in a loop until EOF or max_bytes is reached, then closes the file descriptor.

let buf: &i8 = alloc_pages(4)       // 16KB buffer
let n = fs_read_file("/etc/hostname", buf, 16384)
if n > 0 {
    // buf[0..n] contains the file data
    syscall(1, 1, buf, n)            // write to stdout
}

Returns: Total bytes read, or -1 on error (file not found, permission denied, etc.).

fs_write_file

fn fs_write_file(path: &i8, data: &i8, len: i64) -> i64

Write len bytes to a file. Creates the file if it does not exist. Truncates the file if it does exist. File is created with mode 0644.

let msg = "Jda was here\n"
let n = fs_write_file("/tmp/test.txt", msg, 13)
print(n)   // 13

Returns: Bytes written, or -1 on error.

fs_append_file

fn fs_append_file(path: &i8, data: &i8, len: i64) -> i64

Append len bytes to a file. Creates the file if it does not exist. Opens with O_WRONLY | O_CREAT | O_APPEND.

fs_append_file("/tmp/log.txt", "line 1\n", 7)
fs_append_file("/tmp/log.txt", "line 2\n", 7)

Returns: Bytes written, or -1 on error.

fs_exists

fn fs_exists(path: &i8) -> i64

Check whether a file (or directory) exists using the access syscall.

if fs_exists("/tmp/myfile.txt") == 1 {
    // file exists, safe to read
}

Returns: 1 if the path exists, 0 otherwise.

fn fs_unlink(path: &i8) -> i64

Delete a file. Uses the unlink syscall (87).

let r = fs_unlink("/tmp/temp.txt")
if r == 0 { print(1) }   // deleted

Returns: 0 on success, -1 on error.

fs_mkdir

fn fs_mkdir(path: &i8) -> i64

Create a directory with permissions 0755 (rwxr-xr-x). Uses the mkdir syscall (83).

fs_mkdir("/tmp/myapp")
fs_mkdir("/tmp/myapp/data")

Returns: 0 on success, -1 on error (directory already exists, permission denied, etc.).

fs_file_size

fn fs_file_size(path: &i8) -> i64

Get the size of a file in bytes. Uses the stat syscall and reads the size field from the stat buffer (offset 48).

let size = fs_file_size("/tmp/data.bin")
if size > 0 {
    let pages = size / 4096 + 1
    let buf: &i8 = alloc_pages(pages)
    fs_read_file("/tmp/data.bin", buf, size)
}

Returns: File size in bytes, or -1 on error.

Low-Level Primitives

These single-syscall wrapper functions are used internally. They are exported but intended for advanced use only.

FunctionSignatureSyscallDescription
_fs_open_read(path: &i8) -> i64open (2)Open file for reading
_fs_open_write(path: &i8) -> i64open (2)Open file for writing (O_WRONLY|O_CREAT|O_TRUNC)
_fs_open_append(path: &i8) -> i64open (2)Open file for appending
_fs_close(fd: i64) -> i64close (3)Close a file descriptor
_fs_write(fd: i64, data: &i8, len: i64) -> i64write (1)Write bytes to file descriptor
_fs_read(fd: i64, buf: &i8, max: i64) -> i64read (0)Read bytes from file descriptor
_fs_access(path: &i8) -> i64access (21)Check file accessibility
_fs_unlink_raw(path: &i8) -> i64unlink (87)Raw unlink syscall
_fs_mkdir_raw(path: &i8) -> i64mkdir (83)Raw mkdir syscall
_fs_stat(path: &i8, statbuf: &i8) -> i64stat (4)Raw stat syscall
_fs_rename_raw(src: &i8, dst: &i8) -> i64rename (82)Raw rename syscall