OS
stdlib::os exposes the host machine and the running process's identity: which OS and CPU you compiled for, the process ID, the current working directory, the executable's path, hardware facts (CPU count, RAM, uptime), platform-native standard directories, terminal detection, and a one-shot shell escape.
Functions come in two flavors:
- Compile-time facts return a value directly (
string/bool/i32). These cannot meaningfully fail:os_name,os_arch, theos_is_*predicates, the separators,os_pid, andos_is_tty. - Runtime queries return a
!TResult. EachErrcarries a human-readable reason, and several areErron platforms that don't expose the metric (e.g.os_ppid/os_uid/os_gid/os_loadavg_1mon Windows).
Import
import stdlib::os::*;
Full catalog
All 36 public items at a glance. The Fails? column flags which return !T and on which platform the call typically becomes Err.
| Function | Signature | Fails? | Description |
|---|---|---|---|
os_name |
fn os_name() -> string |
never | OS family string. |
os_arch |
fn os_arch() -> string |
never | CPU architecture string. |
os_is_windows |
fn os_is_windows() -> bool |
never | true on Windows. |
os_is_posix |
fn os_is_posix() -> bool |
never | true on Linux/macOS/*BSD. |
os_is_linux |
fn os_is_linux() -> bool |
never | true only on Linux. |
os_is_macos |
fn os_is_macos() -> bool |
never | true only on macOS. |
os_has_async_io |
fn os_has_async_io() -> bool |
never | true when the epoll/kqueue reactor is wired. |
os_has_reuseport_balance |
fn os_has_reuseport_balance() -> bool |
never | true when SO_REUSEPORT balances accepts (Linux). |
os_path_sep |
fn os_path_sep() -> string |
never | \ on Windows, / else. |
os_line_sep |
fn os_line_sep() -> string |
never | \r\n on Windows, \n else. |
os_path_list_sep |
fn os_path_list_sep() -> string |
never | ; on Windows, : else. |
os_pid |
fn os_pid() -> i32 |
never | Current process ID. |
os_ppid |
fn os_ppid() -> !i32 |
Windows | Parent process ID. |
os_uid |
fn os_uid() -> !i32 |
Windows | POSIX user ID. |
os_gid |
fn os_gid() -> !i32 |
Windows | POSIX group ID. |
os_username |
fn os_username() -> !string |
rare | Login name. |
os_hostname |
fn os_hostname() -> !string |
rare | Machine host name. |
os_kernel_version |
fn os_kernel_version() -> !string |
rare | uname -r / Windows build. |
os_cwd |
fn os_cwd() -> !string |
rare | Current working directory. |
os_chdir |
fn os_chdir(path: string) -> ! |
yes | Change working directory (no value). |
os_exe_path |
fn os_exe_path() -> !string |
rare | Absolute path of the binary. |
os_exe_dir |
fn os_exe_dir() -> !string |
rare | Directory of the binary. |
os_cpu_count |
fn os_cpu_count() -> !i32 |
rare | Logical CPUs. |
os_cpu_count_physical |
fn os_cpu_count_physical() -> !i32 |
rare | Physical cores (falls back to logical). |
os_page_size |
fn os_page_size() -> !i32 |
rare | VM page size in bytes. |
os_memory_total |
fn os_memory_total() -> !u64 |
rare | Total physical RAM (bytes). |
os_memory_free |
fn os_memory_free() -> !u64 |
macOS/BSD | Available RAM (bytes). |
os_uptime_secs |
fn os_uptime_secs() -> !u64 |
rare | Seconds since boot. |
os_loadavg_1m |
fn os_loadavg_1m() -> !f64 |
Windows | 1-minute load average. |
os_temp_dir |
fn os_temp_dir() -> !string |
rare | Per-user temp dir. |
os_home_dir |
fn os_home_dir() -> !string |
rare | User home dir. |
os_config_dir |
fn os_config_dir() -> !string |
rare | Per-user config base dir. |
os_cache_dir |
fn os_cache_dir() -> !string |
rare | Per-user cache base dir. |
os_data_dir |
fn os_data_dir() -> !string |
rare | Per-user data base dir. |
os_is_tty |
fn os_is_tty(fd: i32) -> bool |
never | true if fd is a terminal. |
os_shell |
fn os_shell(cmd: string) -> !i32 |
spawn-fail | Run cmd through the OS shell. |
Platform identity (compile-time, infallible)
These reflect the build target — the platform the binary was compiled for — and never fail.
| Function | Signature | Description |
|---|---|---|
os_name |
fn os_name() -> string |
OS family: "linux", "windows", "macos", "freebsd", "openbsd", "netbsd", or "unknown". |
os_arch |
fn os_arch() -> string |
CPU arch: "x86_64", "aarch64", "arm", "x86", "riscv64", or "unknown". |
os_is_windows |
fn os_is_windows() -> bool |
true on Windows. |
os_is_posix |
fn os_is_posix() -> bool |
true on POSIX-y systems (Linux, macOS, *BSD); false on Windows. |
os_is_linux |
fn os_is_linux() -> bool |
true only on Linux. |
os_is_macos |
fn os_is_macos() -> bool |
true only on macOS / Darwin (os_is_posix() is also true). |
os_has_async_io |
fn os_has_async_io() -> bool |
true when the async I/O reactor (epoll/kqueue) is wired; false where I/O falls back to blocking sync. |
os_has_reuseport_balance |
fn os_has_reuseport_balance() -> bool |
true when SO_REUSEPORT actually load-balances accepts (Linux only today). |
os_path_sep |
fn os_path_sep() -> string |
Path component separator: \ on Windows, / elsewhere. |
os_line_sep |
fn os_line_sep() -> string |
Line ending: "\r\n" on Windows, "\n" elsewhere. |
os_path_list_sep |
fn os_path_list_sep() -> string |
PATH-list separator: ; on Windows, : elsewhere. |
import stdlib::os::*;
fn main() -> i32 {
println!("os:", os_name());
println!("arch:", os_arch());
if os_is_windows() {
println!("on windows, sep =", os_path_sep());
} else {
println!("on posix, sep =", os_path_sep());
}
if os_is_linux() { println!("linux"); }
if os_is_macos() { println!("macos"); }
if os_is_posix() { println!("posix"); }
println!("path list sep:", os_path_list_sep());
let line: string = format!("hello{}", os_line_sep());
println!(line);
if os_has_async_io() { println!("reactor active"); }
if os_has_reuseport_balance() { println!("reuseport balances"); }
return 0;
}
Dispatching on os_name
match only matches enum variants / some/none / _ — not string literals. To branch on the OS family, compare with .eq in an if/else chain:
import stdlib::os::*;
fn opener() -> string {
let n: string = os_name();
if n.eq("macos") { return "open"; }
if n.eq("windows") { return "start"; }
return "xdg-open";
}
fn main() -> i32 {
println!("url opener for", os_name(), "is", opener());
let sep: string = os_line_sep();
let doc: string = format!("line1{}line2{}", sep, sep);
println!(doc);
return 0;
}
Runtime branching on the reactor
os_has_async_io lets a server decide whether it is safe to spawn a coroutine per connection (true with a reactor) or must serve serially inline (the only correct behaviour when read/write block the calling thread):
if os_has_async_io() { spawn handle(c); }
else { handle(c); }
os_has_reuseport_balance is the companion for worker pools: when true, each worker can bind_reuseport and let the kernel balance accepts; when false, bind one shared listener and have N threads accept() on it.
Splitting $PATH
Use os_path_list_sep when splitting $PATH / %PATH% — it is ; on Windows but : on POSIX, and hard-coding either breaks the other platform:
import stdlib::os::*;
import stdlib::env::*;
fn main() -> i32 {
let path: string = env_get("PATH");
let sep: string = os_path_list_sep(); // ";" on Windows, ":" else
let dirs: *Vector<string> = path.split(sep);
println!("PATH has", dirs.len(), "entries");
let mut i: i32 = 0;
while i < dirs.len() {
let d: string = dirs.get(i);
if !d.eq("") { println!(" ", d); }
i = i + 1;
}
return 0;
}
Process identity
| Function | Signature | Description |
|---|---|---|
os_pid |
fn os_pid() -> i32 |
Current process ID. Always positive; never fails. |
os_ppid |
fn os_ppid() -> !i32 |
Parent process ID. Err("ppid not available") on Windows. |
os_uid |
fn os_uid() -> !i32 |
POSIX user ID. Err on Windows (no numeric UID). |
os_gid |
fn os_gid() -> !i32 |
POSIX group ID. Err on Windows. |
os_username |
fn os_username() -> !string |
Login name ($USER/getpwuid on POSIX, GetUserNameA on Windows). |
os_hostname |
fn os_hostname() -> !string |
Machine host name. |
os_kernel_version |
fn os_kernel_version() -> !string |
uname -r on POSIX; <major>.<minor>.<build> on Windows. |
os_pid returns a bare i32 — no Result to unwrap. The rest return !T; read .ok, .val, and .err:
import stdlib::os::*;
fn main() -> i32 {
println!("pid :", os_pid()); // bare i32, infallible
let pp: !i32 = os_ppid(); // Err on Windows
if pp.ok { println!("ppid :", pp.val); }
else { println!("ppid :", pp.err); }
let u: !i32 = os_uid(); // Err on Windows
if u.ok { println!("uid :", u.val); }
let g: !i32 = os_gid(); // Err on Windows
if g.ok { println!("gid :", g.val); }
let user: !string = os_username();
if user.ok { println!("user :", user.val); }
let host: !string = os_hostname();
if host.ok { println!("host :", host.val); }
let kv: !string = os_kernel_version();
if kv.ok { println!("kernel :", kv.val); }
// uid == 0 means root on POSIX.
if u.ok && u.val == 0 { println!("(running as root)"); }
return 0;
}
Current directory and executable
| Function | Signature | Description |
|---|---|---|
os_cwd |
fn os_cwd() -> !string |
Current working directory, no trailing separator. |
os_chdir |
fn os_chdir(path: string) -> ! |
Change the process's working directory. Success carries no value — check r.ok. |
os_exe_path |
fn os_exe_path() -> !string |
Absolute path of the running executable. |
os_exe_dir |
fn os_exe_dir() -> !string |
Directory portion of os_exe_path, no trailing separator. |
os_chdir returns a valueless Result (!). On success there is nothing to read; on failure (missing path, no permission) r.ok is false and r.err holds the reason.
A robust pattern is to save the cwd, change into a scratch directory, then restore it — the working directory is process-global, so leaving it changed surprises the rest of your program:
import stdlib::os::*;
fn main() -> i32 {
let saved: !string = os_cwd();
if !saved.ok { println!("no cwd:", saved.err); return 1; }
println!("start:", saved.val);
let tmp: !string = os_temp_dir();
if tmp.ok {
let c: ! = os_chdir(tmp.val);
if c.ok {
let now: !string = os_cwd();
if now.ok { println!("moved to:", now.val); }
} else {
println!("chdir failed:", c.err);
}
}
// Always restore.
let back: ! = os_chdir(saved.val);
if !back.ok { println!("restore failed:", back.err); }
return 0;
}
Finding resources next to the binary
os_exe_dir is the reliable way to locate files shipped alongside your executable, independent of the cwd the user launched from. Build the path with os_path_sep so it works on both Windows and POSIX:
import stdlib::os::*;
fn main() -> i32 {
let exe: !string = os_exe_path();
if exe.ok { println!("running:", exe.val); }
let dir: !string = os_exe_dir();
if dir.ok {
let asset: string = format!("{}{}assets{}logo.png",
dir.val, os_path_sep(), os_path_sep());
println!("asset:", asset);
} else {
println!("exe dir unavailable:", dir.err);
}
return 0;
}
Hardware
All hardware queries return Results. CPU/page counts are !i32; memory and uptime are !u64; load average is !f64.
| Function | Signature | Description |
|---|---|---|
os_cpu_count |
fn os_cpu_count() -> !i32 |
Logical CPUs available to the process. |
os_cpu_count_physical |
fn os_cpu_count_physical() -> !i32 |
Physical cores; falls back to os_cpu_count() when unavailable. |
os_page_size |
fn os_page_size() -> !i32 |
Virtual memory page size in bytes (typically 4096; 16384 on Apple Silicon). |
os_memory_total |
fn os_memory_total() -> !u64 |
Total physical RAM in bytes. |
os_memory_free |
fn os_memory_free() -> !u64 |
Available physical RAM in bytes (snapshot; best-effort on macOS/BSD). |
os_uptime_secs |
fn os_uptime_secs() -> !u64 |
Seconds since system boot. |
os_loadavg_1m |
fn os_loadavg_1m() -> !f64 |
1-minute load average. POSIX-only — Err on Windows. |
A common use is sizing a worker pool from the CPU count while defaulting safely when the query fails:
import stdlib::os::*;
fn main() -> i32 {
let cpus: !i32 = os_cpu_count();
let workers: i32 = if cpus.ok { cpus.val } else { 1 };
println!("spawning", workers, "workers");
let phys: !i32 = os_cpu_count_physical();
if phys.ok { println!("physical cores:", phys.val); }
let pg: !i32 = os_page_size();
if pg.ok { println!("page size:", pg.val, "bytes"); }
let total: !u64 = os_memory_total();
if total.ok { println!("RAM MiB :", (total.val / 1024 / 1024) as i32); }
let free: !u64 = os_memory_free();
if free.ok { println!("free MiB:", (free.val / 1024 / 1024) as i32); }
let up: !u64 = os_uptime_secs();
if up.ok { println!("uptime :", (up.val / 3600) as i32, "h"); }
let load: !f64 = os_loadavg_1m(); // Err on Windows
if load.ok { println!("load 1m :", load.val); }
else { println!("load 1m :", load.err); }
return 0;
}
Standard directories (platform-native)
Each returns a base directory; append your app name. Resolution differs per platform:
| Function | Signature | Linux | macOS | Windows |
|---|---|---|---|---|
os_temp_dir |
fn os_temp_dir() -> !string |
$TMPDIR or /tmp |
$TMPDIR or /tmp |
%TEMP% |
os_home_dir |
fn os_home_dir() -> !string |
$HOME (fallback getpwuid) |
same | %USERPROFILE% |
os_config_dir |
fn os_config_dir() -> !string |
$XDG_CONFIG_HOME or ~/.config |
~/Library/Application Support |
%APPDATA% |
os_cache_dir |
fn os_cache_dir() -> !string |
$XDG_CACHE_HOME or ~/.cache |
~/Library/Caches |
%LOCALAPPDATA% |
os_data_dir |
fn os_data_dir() -> !string |
$XDG_DATA_HOME or ~/.local/share |
~/Library/Application Support |
%APPDATA% |
import stdlib::os::*;
fn main() -> i32 {
let tmp: !string = os_temp_dir();
if tmp.ok { println!("temp:", tmp.val); }
let home: !string = os_home_dir();
if home.ok { println!("home:", home.val); }
let cfg: !string = os_config_dir();
if cfg.ok { println!("config:", cfg.val); }
let cache: !string = os_cache_dir();
if cache.ok { println!("cache:", cache.val); }
let data: !string = os_data_dir();
if data.ok { println!("data:", data.val); }
return 0;
}
A reusable per-app path helper
Wrap the base-dir lookup behind a function that returns !string and propagate the error with ? — the caller gets one clean Result:
import stdlib::os::*;
fn config_path(app: string, file: string) -> !string {
let base: string = os_config_dir()?; // propagate Err
return ok(format!("{}{}{}{}{}", base, os_path_sep(), app, os_path_sep(), file));
}
fn main() -> i32 {
let p: !string = config_path("myapp", "settings.toml");
if p.ok { println!("config at:", p.val); }
else { println!("could not resolve config dir:", p.err); }
return 0;
}
IO state
os_is_tty
fn os_is_tty(fd: i32) -> bool
true if the file descriptor is a terminal. fd: 0 = stdin, 1 = stdout, 2 = stderr. Use it before emitting ANSI color escapes — output piped to a file or another process should stay plain:
import stdlib::os::*;
fn paint(msg: string) -> string {
if os_is_tty(1) { return format!("\x1b[32m{}\x1b[0m", msg); }
return msg;
}
fn main() -> i32 {
println!(paint("build succeeded"));
if !os_is_tty(0) { println!("(stdin is not interactive)"); }
return 0;
}
Subprocess quick — one-liner shell escape
os_shell
fn os_shell(cmd: string) -> !i32
Runs cmd through the OS shell (cmd /c on Windows, /bin/sh -c elsewhere). Returns Ok(exit_code) (0 = success) or Err only if the shell itself failed to launch. Output streams are inherited; capturing output requires shell-level redirection inside cmd.
import stdlib::os::*;
fn main() -> i32 {
let r: !i32 = os_shell("exit 3");
if r.ok {
if r.val == 0 { println!("command succeeded"); }
else { println!("command exited non-zero:", r.val); }
} else {
println!("shell did not spawn:", r.err);
}
return 0;
}
See also
stdlib::env— command-line args, environment variable get/set, andexit.stdlib::fs— reading/writing files and creating the app directories resolved here.stdlib::io— the stdin/stdout/stderr handles gated byos_is_tty.stdlib::process— the fullCommandbuilder thatos_shellis a shortcut for.