Flash 85 lines
// uptime — one-shot uptime monitor for /bin/uptime.
//
// Prints the seconds-since-boot, humanised, as a single key/value row, then
// exits — the focused sibling of sysinfo's broader summary, the same way
// cpuinfo focuses temperature + clock. The value comes from the architectural
// counter (sys_uptime), board-independent, so it reads the same under QEMU and
// on hardware.
//
// Print-and-exit, so it needs neither the alt-screen buffer nor readKey. Same
// coreutil recipe as cpuinfo / sysinfo (flibc _start shim, flibc_mem, single
// R+X PT_LOAD, stack buffers only). Kept out of the CI FSH_SCRIPT like sysinfo:
// the reading is non-deterministic and does not belong in the baseline-
// checkpoint trace. Source is Flash — flashc transpiles it to Zig at build
// time via addFlashSource.
use flibc
use console_ui
link "flibc_start"
link "flibc_mem"
fn sink(bytes []u8) void {
_ = flibc.sys.write_fd(1, bytes.ptr, bytes.len)
}
export fn main(_ usize, _ argv) noreturn {
console_ui.banner(sink, "FlashOS uptime")
var buf [32]u8 = undefined
console_ui.screen.kv(sink, "uptime", uptimeStr(&buf))
flibc.exit()
}
// Seconds since boot, humanised: "<h>h <m>m <s>s", collapsing to "<s>s"
// under a minute. uptime() is monotonic across reads.
fn uptimeStr(buf []mut u8) []u8 {
secs := flibc.sys.uptime()
h := secs / 3600
m := (secs % 3600) / 60
s := secs % 60
var i usize = 0
if h > 0 {
i += u64dec(buf[i..], h)
buf[i] = 'h'
i += 1
buf[i] = ' '
i += 1
}
if h > 0 || m > 0 {
i += u64dec(buf[i..], m)
buf[i] = 'm'
i += 1
buf[i] = ' '
i += 1
}
i += u64dec(buf[i..], s)
buf[i] = 's'
i += 1
return buf[0..i]
}
// Write `v` as decimal ASCII into `out` (>= 20 bytes for the u64 max),
// returning the byte count.
fn u64dec(out []mut u8, v u64) usize {
if v == 0 {
out[0] = '0'
return 1
}
var tmp [20]u8 = undefined
var n usize = 0
var x u64 = v
while x != 0 {
tmp[n] = '0' + #as(u8, #intCast(x % 10))
n += 1
x /= 10
}
var i usize = 0
while i < n {
out[i] = tmp[n - 1 - i]
i += 1
}
return n
}