std.system
Bounded Linux system-information snapshots, implemented in Plenty over
std.fs and std.io. No subprocess, background sampler,
native dependency, or global cache is involved.
local() -> Result[Procfs, IoError]
open_procfs(path: &std.path.Path) -> Result[Procfs, IoError]
local() opens /proc. open_procfs opens another procfs mount or a directory
of captured files; this also supports deterministic tests. Procfs owns a
directory handle and closes it on drop. It resolves reads relative to that
handle, following the rooted filesystem API’s no-follow rules.
import std.system
from std.path import from_text
from std.system import SystemError
def main() -> Result[(), IoError | SystemError]:
# A captured procfs file gives fixed values; std.system.local() reads /proc.
write_text("loadavg", "0.50 0.25 0.10 2/180 4242\n")?
source = std.system.open_procfs(&from_text(".")?)?
load = source.load_average()?
print(load.one_minute, load.runnable_tasks, load.last_pid)?
live = std.system.local()?
print("CPUs found:", live.cpu_count()? > 0)?
Ok(())
0.5 2 4242
CPUs found: True
Queries
Every method returns Result[T, SystemError]. Calls read fresh data; two calls
are not one atomic snapshot. Limits are named optional arguments.
| Method | Result | Source | Defaults |
|---|---|---|---|
cpu_count() | i64 online logical CPU records | stat | max_bytes=1048576 |
memory() | Memory | meminfo | max_bytes=65536 |
load_average() | LoadAverage | loadavg | max_bytes=4096 |
uptime() | Uptime | uptime | max_bytes=4096 |
block_devices() | list[BlockDevice] | partitions | max_bytes=1048576, max_devices=4096 |
disk_io() | list[DiskIo] | diskstats | max_bytes=1048576, max_devices=4096 |
process_ids() | sorted list[u32] | numeric directory entries | max_entries=65536 |
process(pid: u32) | Process | PID/status | max_bytes=65536 |
The generated signature index lists every public record field. For example:
source = std.system.local()?
memory = source.memory(max_bytes=65536)?
print(memory.total_bytes, memory.available_bytes)?
Units and meaning
Memoryreports total/free physical bytes, optional available physical bytes, and total/free swap bytes.MemAvailableis a kernel estimate;Nothingmeans the field is unavailable, not zero. Free memory excludes reclaimable caches and is usually not the useful estimate of allocation headroom.LoadAveragehas 1-, 5-, and 15-minute load values, runnable/total task counts, and the last created PID. Load is not CPU-utilization percent.Uptime.secondsis elapsed boot time, including suspend according to procfs.idle_cpu_secondssums idle time over CPUs and can exceed elapsed time.BlockDevicegives major/minor device numbers, a name, andsize_bytes. Whole disks and partitions can appear; summing them double-counts storage./proc/partitionsreports 1024-byte blocks, so capacity has that granularity. This is not mounted filesystem capacity or free space.DiskIogives reads/writes completed, bytes read/written, currently in-flight requests, and busy milliseconds. Sector counts are converted using Linux’s fixed 512-byte accounting unit. These are raw counters, not rates. Counters can reset on reboot/device replacement or wrap; detect resets before computing differences. Whole disks and partitions overlap here too. New trailing diskstats fields are ignored; the modern eleven-counter prefix is required.Processgives PID, parent PID, the kernel-reported name and state code, real UID, thread count, and optional virtual/resident bytes. Name escaping fromstatusis preserved, including literal backslash escapes; it is not a command line or executable path. Missing memory fields, for example on kernel threads, yieldNothing. Resident memory is an approximate kernel counter.
The CPU count is not an affinity/cgroup-aware worker-pool size. Memory, load, uptime and devices describe what the mounted files expose, often the host even in a container. PIDs follow the mount’s PID namespace and permissions. This API does not infer a container’s effective CPU or memory quota.
Limits, failures, and races
max_bytes is a Positive[i64]; i64.MAX traps, as does process with pid
0. Entry and device bounds are NonNegative[i64]. A byte-limited read probes one extra byte to distinguish
exact-limit EOF from truncation, since proc files often report size zero.
Exceeding any bound returns Limit, never a partial successful result.
process_ids counts all visited directory entries toward its bound,
including non-PID names. Parsing and result storage allocate fallibly; byte
limits bound input size, not exact peak memory.
enum SystemError:
Io(IoError)
Stream(std.io.StreamError)
Allocation(AllocError)
Limit
Malformed(str)
I/O errors keep their original cause, including missing and inaccessible files.
Allocation errors can also occur inside the existing Io/Stream envelopes.
Invalid UTF-8, missing required fields, duplicate selected keys, invalid numbers
and unit-conversion overflow return Malformed(field_or_source). Unknown
meminfo/status keys are ignored. Numeric conversions never truncate or wrap.
Scaling checks the full u64 product and preserves the field-specific
Malformed error on overflow; counts and byte-limit probe offsets are bounded
by their validated limits rather than saturated.
Enumerating PIDs does not read each process’s status or silently skip failures.
Call process(pid) for the records wanted, choosing how to handle disappearance
or access denial. It opens the PID directory once before reading status, avoiding
mixing files from a reused path; the process may still exit and the read may fail.
A returned PID is neither a stable identity nor authority to signal a process.
This first interface has no CPU-utilization sampling, filesystem free-space
query, command-line decoding, cgroup accounting, or process control. For children
owned by the program, use std.process.
Formats follow the kernel’s procfs documentation, disk I/O accounting, and partitions ABI. See the tutorial.