60 lines
1.7 KiB
Rust
60 lines
1.7 KiB
Rust
//! Counts its runs in its own data folder: the `storage` capability, which
|
|
//! it can do without (then it remembers nothing).
|
|
|
|
#![no_std]
|
|
#![forbid(unsafe_code)]
|
|
#![no_main]
|
|
|
|
extern crate libkos;
|
|
|
|
use libkos::fs::Storage;
|
|
use libkos::println;
|
|
use types::address::VirtualAddress;
|
|
|
|
const DATA_BUF_VA: VirtualAddress = VirtualAddress::from_raw(0x0180_0000);
|
|
const COUNT: &[u8] = b"count";
|
|
|
|
/// The number in the file, 0 if there is none yet.
|
|
fn read_count(fs: &mut Storage) -> u64 {
|
|
let Ok(h) = fs.open(COUNT) else { return 0 };
|
|
let mut buf = [0u8; 20];
|
|
let n = fs.read(h, &mut buf).unwrap_or(0);
|
|
let _ = fs.close(h);
|
|
core::str::from_utf8(&buf[..n]).ok().and_then(|s| s.trim().parse().ok()).unwrap_or(0)
|
|
}
|
|
|
|
fn write_count(fs: &mut Storage, count: u64) -> bool {
|
|
let mut digits = [0u8; 20];
|
|
let mut n = 0;
|
|
let mut v = count;
|
|
loop {
|
|
digits[n] = b'0' + (v % 10) as u8;
|
|
n += 1;
|
|
v /= 10;
|
|
if v == 0 {
|
|
break;
|
|
}
|
|
}
|
|
digits[..n].reverse();
|
|
let _ = fs.delete(COUNT);
|
|
let Ok(h) = fs.create(COUNT) else { return false };
|
|
let ok = fs.write(h, &digits[..n]) == Ok(n);
|
|
let _ = fs.close(h);
|
|
ok
|
|
}
|
|
|
|
fn main() {
|
|
let Some(mut fs) = libkos::start::data().and_then(|d| Storage::attach(d, DATA_BUF_VA).ok()) else {
|
|
println!("counter: not allowed to keep anything, so this is run 1 as far as it knows");
|
|
return;
|
|
};
|
|
let count = read_count(&mut fs) + 1;
|
|
if write_count(&mut fs, count) {
|
|
println!("counter: run {} (kept in its own data folder)", count);
|
|
} else {
|
|
println!("counter: run {}, but it could not save that", count);
|
|
}
|
|
}
|
|
|
|
libkos::entry!(main);
|