Skip to main content

Module fs

Module fs 

Source
Expand description

Files, without the byte layout.

§What this replaces

Reading a file today means knowing the wire protocol. From services/shell, abbreviated:

  let stat = fs_request_q(ctx, OP_STAT_FILE, path, &[]);   // three outcome arms
  let sp = stat.payload_bytes();
  let exists = sp.first() == Some(&FS_OK) && sp.len() >= 11 && sp[1] == 1;
  let is_dir = exists && sp[10] == 1;
  let size = u64::from_le_bytes([sp[2], sp[3], sp[4], sp[5], sp[6], sp[7], sp[8], sp[9]]);
  // then loop read_at in IO_CHUNK pieces, checking errors at each step

Roughly thirty lines, every one an opportunity to index the wrong byte. FS_OK was declared independently in four crates, and the shell re-declared 21 of the filesystem’s 27 opcodes. A guessed opcode in one of them (1 where the protocol says 10) made a command write nothing for twelve seconds and report that it was done.

The layout is owned here, once. It is a fact services/fs defines; every other crate was re-deriving it from a comment.

§There is no read_to_string

GodspeedOS has no heap, deliberately (CLAUDE.md §26.6.1: fixed stack arrays and bounded arenas, so the maximum a subsystem can use is readable from its source). A function returning an allocated String cannot exist, and adding an allocator to make this library look like Rust’s would be trading the architecture for a familiar shape.

So the caller owns the buffer:

ⓘ
let mut buf = [0u8; 4096];
let n = fs::read_into(&fs, "/data/hello.txt", &mut buf)?;
io::println(ctx, core::str::from_utf8(&buf[..n]).unwrap_or("<not utf-8>"));

Six lines against thirty, no byte indices, and the bound is visible in the source.

Structs§

Check
What Fs::check repaired, and what it found.
DirEntry
One entry from Fs::list_dir.
Drive
What Fs::drive reports about the storage fs serves.
Fs
A handle to the filesystem service.
Listing
What Fs::list_dir did.
Scrub
What Fs::scrub found. Read-only: it changes nothing on disk.
Stat
What stat found.

Constants§

DIR_PAGE_MAX
The most pages Fs::list_dir will request before stopping and saying so.
IO_CHUNK
The most file content one request can carry, as services/fs frames it (7 * 508). Reads and writes larger than this are split by read_into and write; it is public because a caller sizing its own buffer benefits from knowing the natural stride.
PATH_MAX
The longest path services/fs accepts. A longer one is Error::InvalidInput and is never sent, rather than being silently truncated into a request for a DIFFERENT file.
REASON_MAX
The most of a service-supplied failure reason Fs::reason keeps. Bounded on purpose: the handle is a stack value, so its size must be readable from this line (26.6.1).
SWEEP_SECS
How long to wait for a whole-volume sweep (Fs::check or Fs::scrub).