hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-10-08 22:23:55 +0200
committerhachem <im@hachem.wtf>2026-10-08 22:23:55 +0200
commit852a5b237116e8b53ae18ea8ea00505e44b40dfe (patch)
tree1ed51afcf6471d2a0031d31b67b63f4ec404b9ed /kernel
parentef104148057ab98f80b1560405b5c02768457096 (diff)
feat: file descriptor and proper stdio
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fs.rv18
-rw-r--r--kernel/io.rv37
-rw-r--r--kernel/main.rv4
-rw-r--r--kernel/proc.rv4
-rw-r--r--kernel/seed.rv7
-rw-r--r--kernel/shell.rv32
6 files changed, 79 insertions, 23 deletions
diff --git a/kernel/fs.rv b/kernel/fs.rv
index 23ccd78..1e72dc4 100644
--- a/kernel/fs.rv
+++ b/kernel/fs.rv
@@ -346,6 +346,23 @@ global fs = {
return entry.size
end,
+ # TODO: ts needs a rewrite its not cheap and rewrites every file from scratch
+ write_at = fn(self, path, offset, bytes) do
+ const size = self:size(path)
+ let base = ""
+ if size > 0 do base = self:read_bytes(path, 0, size) end
+ let prefix = ""
+ if offset <= base:len() do prefix = base[0..offset] end
+ else do
+ prefix = base
+ while prefix:len() < offset do prefix = prefix ~ string.of_ascii(0) end
+ end
+ const after = offset + bytes:len()
+ let tail = ""
+ if after < base:len() do tail = base[after..] end
+ return self:store(path, prefix ~ bytes ~ tail)
+ end,
+
cat = fn(self, path) do
if self:ensure() == :false return :nil
const entry = self:resolve(path)
@@ -444,3 +461,4 @@ global fs = {
global fs_store = fn(name, text) fs:store(name, text)
global fs_size = fn(name) fs:size(name)
global fs_read_bytes = fn(name, offset, length) fs:read_bytes(name, offset, length)
+global fs_write_at = fn(name, offset, bytes) fs:write_at(name, offset, bytes)
diff --git a/kernel/io.rv b/kernel/io.rv
new file mode 100644
index 0000000..68b7039
--- /dev/null
+++ b/kernel/io.rv
@@ -0,0 +1,37 @@
+# stdio stuff
+
+global io = {
+ open = fn(self, path, mode) do
+ if mode == "w" do fs:store(path, "") end
+ let offset = 0
+ if mode == "a" do
+ const size = fs:size(path)
+ if size > 0 do offset = size end
+ end
+ return { path = path, offset = offset }
+ end,
+
+ read = fn(self, handle, count) do
+ const data = fs:read_bytes(handle.path, handle.offset, count)
+ handle.offset += data:len()
+ return data
+ end,
+
+ read_all = fn(self, handle) do
+ const size = fs:size(handle.path)
+ if size <= handle.offset return ""
+ const data = fs:read_bytes(handle.path, handle.offset, size - handle.offset)
+ handle.offset += data:len()
+ return data
+ end,
+
+ write = fn(self, handle, data) do
+ fs:write_at(handle.path, handle.offset, data)
+ handle.offset += data:len()
+ return data:len()
+ end,
+
+ seek = fn(self, handle, offset) do handle.offset = offset end,
+ tell = fn(self, handle) handle.offset,
+ close = fn(self, handle) :nil,
+}
diff --git a/kernel/main.rv b/kernel/main.rv
index 3363bde..93de758 100644
--- a/kernel/main.rv
+++ b/kernel/main.rv
@@ -16,9 +16,9 @@ if (disk_sectors() != 0 and fs.ready == :false) do
end
# lung will be happy
-const default_face = load_ttf("/fonts/terminess.ttf", 32)
+const default_face = load_ttf("/usr/share/terminess.ttf", 32)
if default_face != :nil do
- add_font("terminess", default_face.glyphs, default_face.width, default_face.height, :ttf, "/fonts/terminess.ttf", 32)
+ add_font("terminess", default_face.glyphs, default_face.width, default_face.height, :ttf, "/usr/share/terminess.ttf", 32)
console:set_font(find_font("terminess"))
end
diff --git a/kernel/proc.rv b/kernel/proc.rv
index 5019fa8..92d48f1 100644
--- a/kernel/proc.rv
+++ b/kernel/proc.rv
@@ -67,8 +67,8 @@ end
fn run_prog(name, arg) do
let bare_name = name
- if bare_name:starts_with?("/bin/") bare_name = bare_name[5..]
- const path = "/bin/#{bare_name}"
+ if bare_name:starts_with?("/usr/bin/") bare_name = bare_name[9..]
+ const path = "/usr/bin/#{bare_name}"
if fs:size(path) < 0 return :false
return load_file_elf(path, arg)
end
diff --git a/kernel/seed.rv b/kernel/seed.rv
index 058b57a..f673f68 100644
--- a/kernel/seed.rv
+++ b/kernel/seed.rv
@@ -2,8 +2,9 @@
fn seed_bin() do
fs:mkdir("/bin")
+ fs:mkdir("/usr/bin")
for index in 0..prog_count() do
- fs:store("/bin/#{prog_name(index)}", phys_to_str(prog_phys(index), prog_size(index)))
+ fs:store("/usr/bin/#{prog_name(index)}", phys_to_str(prog_phys(index), prog_size(index)))
end
for index in 0..script_count() do
fs:store("/bin/#{script_name(index)}.rv", script_src(index))
@@ -11,9 +12,9 @@ fn seed_bin() do
end
fn seed_fonts() do
- fs:mkdir("/fonts")
+ fs:mkdir("/usr/share")
for index in 0..font_count() do
- fs:store("/fonts/#{font_name(index)}", phys_to_str(font_phys(index), font_size(index)))
+ fs:store("/usr/share/#{font_name(index)}", phys_to_str(font_phys(index), font_size(index)))
end
end
diff --git a/kernel/shell.rv b/kernel/shell.rv
index 31cc70e..2811e5a 100644
--- a/kernel/shell.rv
+++ b/kernel/shell.rv
@@ -22,26 +22,26 @@ end
fn cmd_help(context) do
help_group("shell", "shell")
help_group("gils (builtin)", "gils")
- # the rest of gils, and the programs, are real files in /bin now
- const items = fs:entries("/bin")
- if items != :nil do
+ # gils scripts are real files in /bin, native programs in /usr/bin
+ const scripts = fs:entries("/bin")
+ if scripts != :nil do
puts("\n gils (/bin scripts)\n")
- for index in 0..items:len() do
- const name = items[index].name
+ for index in 0..scripts:len() do
+ const name = scripts[index].name
if (name:len() > 3 and name[(name:len() - 3)..] == ".rv") do help_row(name[0..(name:len() - 3)], "") end
end
- puts("\n programs (/bin)\n")
- for index in 0..items:len() do
- const name = items[index].name
- if (name:len() <= 3 or name[(name:len() - 3)..] != ".rv") do help_row(name, "") end
- end
+ end
+ const progs = fs:entries("/usr/bin")
+ if progs != :nil do
+ puts("\n programs (/usr/bin)\n")
+ for index in 0..progs:len() do help_row(progs[index].name, "") end
end
puts("\n fonts (font <name>)\n")
for index in 0..fonts:len() do help_row(fonts[index].name, "8x#{fonts[index].height}") end
- const font_files = fs:entries("/fonts")
+ const font_files = fs:entries("/usr/share")
if font_files != :nil do
- puts("\n fonts on disk (font load /fonts/x.psf)\n")
+ puts("\n fonts on disk (font load /usr/share/x.psf)\n")
for index in 0..font_files:len() do help_row(font_files[index].name, "") end
end
puts("\n")
@@ -186,8 +186,8 @@ fn font_file(name) do
if fs:size(p ~ ".psf") >= 0 return { path = p ~ ".psf", kind = :psf }
return { path = p, kind = :none }
end
- if fs:size("/fonts/#{name}.psf") >= 0 return { path = "/fonts/#{name}.psf", kind = :psf }
- if fs:size("/fonts/#{name}.ttf") >= 0 return { path = "/fonts/#{name}.ttf", kind = :ttf }
+ if fs:size("/usr/share/#{name}.psf") >= 0 return { path = "/usr/share/#{name}.psf", kind = :psf }
+ if fs:size("/usr/share/#{name}.ttf") >= 0 return { path = "/usr/share/#{name}.ttf", kind = :ttf }
return { path = name, kind = :none }
end
@@ -196,7 +196,7 @@ fn cmd_font(context) do
puts("fonts:")
for index in 0..fonts:len() do puts(" #{fonts[index].name}(#{fonts[index].width}x#{fonts[index].height})") end
puts("\n")
- const font_files = fs:entries("/fonts")
+ const font_files = fs:entries("/usr/share")
if font_files != :nil do
puts("on disk:")
for index in 0..font_files:len() do puts(" #{font_files[index].name}") end
@@ -291,7 +291,7 @@ fn exec_file(target) do
else do
candidates:push(expand_path(target))
candidates:push(expand_path(target) ~ ".rv")
- candidates:push("/bin/#{target}")
+ candidates:push("/usr/bin/#{target}")
candidates:push("/bin/#{target}.rv")
end
for index in 0..candidates:len() do