OS
stdlib::os expõe a identidade da máquina hospedeira e do processo em execução: qual sistema operacional e CPU foram usados na compilação, o ID do processo, o diretório de trabalho atual, o caminho do executável, informações de hardware (contagem de CPUs, RAM, tempo de atividade), diretórios padrão nativos da plataforma, detecção de terminal e um atalho para execução de comandos no shell.
As funções se dividem em duas categorias:
- Fatos de tempo de compilação retornam um valor diretamente (
string/bool/i32). Essas funções não podem falhar de forma significativa:os_name,os_arch, os predicadosos_is_*, os separadores,os_pideos_is_tty. - Consultas em tempo de execução retornam um Result
!T. CadaErrcarrega uma razão legível por humanos, e várias retornamErrem plataformas que não expõem a métrica (por exemplo,os_ppid/os_uid/os_gid/os_loadavg_1mno Windows).
Import
import stdlib::os::*;
Catálogo completo
Todos os 36 itens públicos de relance. A coluna Falha? indica quais retornam !T e em qual plataforma a chamada tipicamente vira Err.
| Função | Assinatura | Falha? | Descrição |
|---|---|---|---|
os_name |
fn os_name() -> string |
nunca | String da família do SO. |
os_arch |
fn os_arch() -> string |
nunca | String da arquitetura da CPU. |
os_is_windows |
fn os_is_windows() -> bool |
nunca | true no Windows. |
os_is_posix |
fn os_is_posix() -> bool |
nunca | true no Linux/macOS/*BSD. |
os_is_linux |
fn os_is_linux() -> bool |
nunca | true apenas no Linux. |
os_is_macos |
fn os_is_macos() -> bool |
nunca | true apenas no macOS. |
os_has_async_io |
fn os_has_async_io() -> bool |
nunca | true quando o reactor epoll/kqueue está ativo. |
os_has_reuseport_balance |
fn os_has_reuseport_balance() -> bool |
nunca | true quando SO_REUSEPORT balanceia accepts (Linux). |
os_path_sep |
fn os_path_sep() -> string |
nunca | \ no Windows, / nos demais. |
os_line_sep |
fn os_line_sep() -> string |
nunca | \r\n no Windows, \n nos demais. |
os_path_list_sep |
fn os_path_list_sep() -> string |
nunca | ; no Windows, : nos demais. |
os_pid |
fn os_pid() -> i32 |
nunca | ID do processo atual. |
os_ppid |
fn os_ppid() -> !i32 |
Windows | ID do processo pai. |
os_uid |
fn os_uid() -> !i32 |
Windows | ID de usuário POSIX. |
os_gid |
fn os_gid() -> !i32 |
Windows | ID de grupo POSIX. |
os_username |
fn os_username() -> !string |
raro | Nome de login. |
os_hostname |
fn os_hostname() -> !string |
raro | Nome do host da máquina. |
os_kernel_version |
fn os_kernel_version() -> !string |
raro | uname -r / build do Windows. |
os_cwd |
fn os_cwd() -> !string |
raro | Diretório de trabalho atual. |
os_chdir |
fn os_chdir(path: string) -> ! |
sim | Muda o diretório de trabalho (sem valor de retorno). |
os_exe_path |
fn os_exe_path() -> !string |
raro | Caminho absoluto do binário. |
os_exe_dir |
fn os_exe_dir() -> !string |
raro | Diretório do binário. |
os_cpu_count |
fn os_cpu_count() -> !i32 |
raro | CPUs lógicas. |
os_cpu_count_physical |
fn os_cpu_count_physical() -> !i32 |
raro | Núcleos físicos (cai para lógico se indisponível). |
os_page_size |
fn os_page_size() -> !i32 |
raro | Tamanho de página de memória virtual em bytes. |
os_memory_total |
fn os_memory_total() -> !u64 |
raro | RAM física total (bytes). |
os_memory_free |
fn os_memory_free() -> !u64 |
macOS/BSD | RAM disponível (bytes). |
os_uptime_secs |
fn os_uptime_secs() -> !u64 |
raro | Segundos desde o boot. |
os_loadavg_1m |
fn os_loadavg_1m() -> !f64 |
Windows | Média de carga em 1 minuto. |
os_temp_dir |
fn os_temp_dir() -> !string |
raro | Diretório temporário por usuário. |
os_home_dir |
fn os_home_dir() -> !string |
raro | Diretório home do usuário. |
os_config_dir |
fn os_config_dir() -> !string |
raro | Diretório base de configuração por usuário. |
os_cache_dir |
fn os_cache_dir() -> !string |
raro | Diretório base de cache por usuário. |
os_data_dir |
fn os_data_dir() -> !string |
raro | Diretório base de dados por usuário. |
os_is_tty |
fn os_is_tty(fd: i32) -> bool |
nunca | true se fd é um terminal. |
os_shell |
fn os_shell(cmd: string) -> !i32 |
falha no spawn | Executa cmd pelo shell do SO. |
Identidade da plataforma (tempo de compilação, infalível)
Essas funções refletem o alvo de compilação — a plataforma para a qual o binário foi compilado — e nunca falham.
| Função | Assinatura | Descrição |
|---|---|---|
os_name |
fn os_name() -> string |
Família do SO: "linux", "windows", "macos", "freebsd", "openbsd", "netbsd" ou "unknown". |
os_arch |
fn os_arch() -> string |
Arquitetura da CPU: "x86_64", "aarch64", "arm", "x86", "riscv64" ou "unknown". |
os_is_windows |
fn os_is_windows() -> bool |
true no Windows. |
os_is_posix |
fn os_is_posix() -> bool |
true em sistemas POSIX (Linux, macOS, *BSD); false no Windows. |
os_is_linux |
fn os_is_linux() -> bool |
true apenas no Linux. |
os_is_macos |
fn os_is_macos() -> bool |
true apenas no macOS / Darwin (os_is_posix() também é true). |
os_has_async_io |
fn os_has_async_io() -> bool |
true quando o reactor de IO assíncrono (epoll/kqueue) está ativo; false quando o IO cai para bloqueante síncrono. |
os_has_reuseport_balance |
fn os_has_reuseport_balance() -> bool |
true quando SO_REUSEPORT realmente balanceia accepts (apenas Linux por ora). |
os_path_sep |
fn os_path_sep() -> string |
Separador de componentes de caminho: \ no Windows, / nos demais. |
os_line_sep |
fn os_line_sep() -> string |
Terminador de linha: "\r\n" no Windows, "\n" nos demais. |
os_path_list_sep |
fn os_path_list_sep() -> string |
Separador de lista PATH: ; no Windows, : nos demais. |
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;
}
Ramificando com os_name
match só combina variantes de enum / some/none / _ — não literais de string. Para ramificar pela família do SO, compare com .eq em uma cadeia if/else:
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;
}
Ramificação em tempo de execução com base no reactor
os_has_async_io permite que um servidor decida se é seguro lançar uma corrotina por conexão (verdadeiro com um reactor) ou se deve atender de forma síncrona inline (o único comportamento correto quando read/write bloqueiam a thread chamadora):
if os_has_async_io() { spawn handle(c); }
else { handle(c); }
os_has_reuseport_balance é o complemento para pools de workers: quando true, cada worker pode usar bind_reuseport e deixar o kernel balancear os accepts; quando false, vincule um único listener compartilhado e tenha N threads chamando accept() nele.
Dividindo o $PATH
Use os_path_list_sep ao dividir $PATH / %PATH% — é ; no Windows mas : no POSIX, e usar qualquer um dos dois fixo quebra a outra plataforma:
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;
}
Identidade do processo
| Função | Assinatura | Descrição |
|---|---|---|
os_pid |
fn os_pid() -> i32 |
ID do processo atual. Sempre positivo; nunca falha. |
os_ppid |
fn os_ppid() -> !i32 |
ID do processo pai. Err("ppid not available") no Windows. |
os_uid |
fn os_uid() -> !i32 |
ID de usuário POSIX. Err no Windows (sem UID numérico). |
os_gid |
fn os_gid() -> !i32 |
ID de grupo POSIX. Err no Windows. |
os_username |
fn os_username() -> !string |
Nome de login ($USER/getpwuid no POSIX, GetUserNameA no Windows). |
os_hostname |
fn os_hostname() -> !string |
Nome do host da máquina. |
os_kernel_version |
fn os_kernel_version() -> !string |
uname -r no POSIX; <major>.<minor>.<build> no Windows. |
os_pid retorna um i32 direto — sem Result para desempacotar. Os demais retornam !T; leia .ok, .val e .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 significa root no POSIX.
if u.ok && u.val == 0 { println!("(running as root)"); }
return 0;
}
Diretório atual e executável
| Função | Assinatura | Descrição |
|---|---|---|
os_cwd |
fn os_cwd() -> !string |
Diretório de trabalho atual, sem separador no final. |
os_chdir |
fn os_chdir(path: string) -> ! |
Muda o diretório de trabalho do processo. O sucesso não carrega valor — verifique r.ok. |
os_exe_path |
fn os_exe_path() -> !string |
Caminho absoluto do executável em execução. |
os_exe_dir |
fn os_exe_dir() -> !string |
Porção de diretório de os_exe_path, sem separador no final. |
os_chdir retorna um Result sem valor (!). Em caso de sucesso não há nada a ler; em caso de falha (caminho inexistente, sem permissão) r.ok é false e r.err contém o motivo.
Um padrão robusto é salvar o cwd, mudar para um diretório temporário e restaurá-lo — o diretório de trabalho é global ao processo, então deixá-lo alterado surpreende o restante do programa:
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);
}
}
// Sempre restaurar.
let back: ! = os_chdir(saved.val);
if !back.ok { println!("restore failed:", back.err); }
return 0;
}
Localizando recursos próximos ao binário
os_exe_dir é a maneira confiável de localizar arquivos distribuídos junto ao executável, independentemente do cwd de onde o usuário o iniciou. Construa o caminho com os_path_sep para que funcione tanto no Windows quanto no 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
Todas as consultas de hardware retornam Results. Contagens de CPU/página são !i32; memória e uptime são !u64; média de carga é !f64.
| Função | Assinatura | Descrição |
|---|---|---|
os_cpu_count |
fn os_cpu_count() -> !i32 |
CPUs lógicas disponíveis para o processo. |
os_cpu_count_physical |
fn os_cpu_count_physical() -> !i32 |
Núcleos físicos; cai para os_cpu_count() quando indisponível. |
os_page_size |
fn os_page_size() -> !i32 |
Tamanho de página de memória virtual em bytes (tipicamente 4096; 16384 no Apple Silicon). |
os_memory_total |
fn os_memory_total() -> !u64 |
RAM física total em bytes. |
os_memory_free |
fn os_memory_free() -> !u64 |
RAM física disponível em bytes (instantâneo; melhor esforço no macOS/BSD). |
os_uptime_secs |
fn os_uptime_secs() -> !u64 |
Segundos desde o boot do sistema. |
os_loadavg_1m |
fn os_loadavg_1m() -> !f64 |
Média de carga em 1 minuto. Apenas POSIX — Err no Windows. |
Um uso comum é dimensionar um pool de workers a partir da contagem de CPUs com um fallback seguro quando a consulta falha:
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;
}
Diretórios padrão (nativos da plataforma)
Cada função retorna um diretório base; acrescente o nome do seu app. A resolução varia por plataforma:
| Função | Assinatura | Linux | macOS | Windows |
|---|---|---|---|---|
os_temp_dir |
fn os_temp_dir() -> !string |
$TMPDIR ou /tmp |
$TMPDIR ou /tmp |
%TEMP% |
os_home_dir |
fn os_home_dir() -> !string |
$HOME (fallback getpwuid) |
igual | %USERPROFILE% |
os_config_dir |
fn os_config_dir() -> !string |
$XDG_CONFIG_HOME ou ~/.config |
~/Library/Application Support |
%APPDATA% |
os_cache_dir |
fn os_cache_dir() -> !string |
$XDG_CACHE_HOME ou ~/.cache |
~/Library/Caches |
%LOCALAPPDATA% |
os_data_dir |
fn os_data_dir() -> !string |
$XDG_DATA_HOME ou ~/.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;
}
Um helper reutilizável de caminho por app
Encapsule a busca pelo diretório base em uma função que retorna !string e propague o erro com ? — o chamador recebe um Result limpo:
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;
}
Estado de IO
os_is_tty
fn os_is_tty(fd: i32) -> bool
true se o descritor de arquivo for um terminal. fd: 0 = stdin, 1 = stdout, 2 = stderr. Use antes de emitir sequências de escape ANSI de cor — saída redirecionada para um arquivo ou outro processo deve permanecer sem formatação:
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;
}
Subprocesso rápido — atalho de shell de uma linha
os_shell
fn os_shell(cmd: string) -> !i32
Executa cmd pelo shell do SO (cmd /c no Windows, /bin/sh -c nos demais). Retorna Ok(exit_code) (0 = sucesso) ou Err apenas se o próprio shell falhou ao ser iniciado. Os streams de saída são herdados; capturar a saída requer redirecionamento a nível de shell dentro de 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;
}
Veja também
stdlib::env— argumentos de linha de comando, get/set de variáveis de ambiente eexit.stdlib::fs— leitura e escrita de arquivos e criação dos diretórios de app resolvidos aqui.stdlib::io— os handles de stdin/stdout/stderr controlados poros_is_tty.stdlib::process— o construtor completoCommanddo qualos_shellé um atalho.