hachem.wtf
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-10-07 22:57:09 +0200
committerhachem <im@hachem.wtf>2026-10-07 22:57:09 +0200
commit5f6deca073728d0dafa2cd47d841b28d54af3aaf (patch)
treeaea2a645d819d52aa95fcc27056a64a355ef64b7
parente55291a32a8b3f7b5c105cd79e86f3c19f19b3d4 (diff)
fix: relative paths + run revo scripts
-rw-r--r--gils/cat.rv2
-rw-r--r--gils/cp.rv4
-rw-r--r--gils/ed.rv4
-rw-r--r--gils/gils.rv20
-rw-r--r--gils/head.rv2
-rw-r--r--gils/ls.rv2
-rw-r--r--gils/mkdir.rv2
-rw-r--r--gils/mv.rv4
-rw-r--r--gils/rm.rv2
-rw-r--r--gils/tail.rv2
-rw-r--r--gils/touch.rv2
-rw-r--r--gils/tree.rv2
-rw-r--r--gils/wc.rv2
-rw-r--r--kernel/shell.rv43
14 files changed, 62 insertions, 31 deletions
diff --git a/gils/cat.rv b/gils/cat.rv
index 1cca54b..220ce93 100644
--- a/gils/cat.rv
+++ b/gils/cat.rv
@@ -4,7 +4,7 @@ const context = env.ctx
const parsed = arg_name(context.rest, 0)
if parsed.name:len() == 0 do puts("usage: cat <path>\n") end
else do
- const path = abspath(parsed.name)
+ const path = expand_path(parsed.name)
if vfs_owns(path) do vfs_cat(path) end
else do fs:cat(path) end
end
diff --git a/gils/cp.rv b/gils/cp.rv
index 5988e54..5006acb 100644
--- a/gils/cp.rv
+++ b/gils/cp.rv
@@ -4,8 +4,8 @@
const context = env.ctx
if context.argv:len() < 3 do puts("usage: cp <source> <destination>\n") end
else do
- const source = abspath(context.argv[1])
- const destination = abspath(context.argv[2])
+ const source = expand_path(context.argv[1])
+ const destination = expand_path(context.argv[2])
const size = fs:size(source)
if size < 0 do puts("cp: #{source}: no such file\n") end
else do
diff --git a/gils/ed.rv b/gils/ed.rv
index 2572ba3..7f1d849 100644
--- a/gils/ed.rv
+++ b/gils/ed.rv
@@ -112,7 +112,7 @@ fn ed_write(state, command) do
let path = state.path
if command:len() > 1 do
const filename = command[1..]:trim()
- if filename:len() > 0 do path = abspath(filename) end
+ if filename:len() > 0 do path = expand_path(filename) end
end
if path:len() == 0 do puts("?\n") return :nil end
const contents = ed_join(state.lines)
@@ -134,7 +134,7 @@ fn gils_ed(context) do
ed_state.input = :false
ed_state.dirty = :false
ed_state.lines = {}
- ed_state.path = if context.argv:len() > 1 abspath(context.argv[1]) else ""
+ ed_state.path = if context.argv:len() > 1 expand_path(context.argv[1]) else ""
if ed_state.path:len() > 0 do
const size = fs:size(ed_state.path)
if size > 0 do
diff --git a/gils/gils.rv b/gils/gils.rv
index afd0bbd..08c97cd 100644
--- a/gils/gils.rv
+++ b/gils/gils.rv
@@ -24,23 +24,23 @@ end
# scripts read their args off env.ctx, stashed here before eval
global env = { ctx = :nil }
-global abspath = fn(arg) do
- if arg:len() == 0 return wd.path
- let path = arg
- if arg[0] != "/" do
- if wd.path == "/" do path = "/#{arg}" end
- else do path = "#{wd.path}/#{arg}" end
+# first use of unless in history
+global expand_path = fn(path) do
+ if path:len() == 0 return wd.path
+ unless (path[0] == "/") do
+ const slash = unless (wd.path == "/") "/" else ""
+ path = "#{wd.path}#{slash}#{path}"
end
- while (path:len() > 1 and path[path:len() - 1] == "/") do path = path[0..(path:len() - 1)] end
return path
end
-fn run_script(name, ctx) do
- const path = "/bin/#{name}.rv"
+fn run_script_path(path, label, ctx) do
const size = fs:size(path)
if size < 0 return :false
env.ctx = ctx
const error_msg = eval_script(fs:read_bytes(path, 0, size))
- if error_msg != :nil do puts("#{name}: #{error_msg}\n") end
+ if error_msg != :nil do puts("#{label}: #{error_msg}\n") end
return :true
end
+
+fn run_script(name, ctx) run_script_path("/bin/#{name}.rv", name, ctx)
diff --git a/gils/head.rv b/gils/head.rv
index edfd096..addd11a 100644
--- a/gils/head.rv
+++ b/gils/head.rv
@@ -18,7 +18,7 @@ else do
let limit = 10
let path_arg = context.argv[1]
if (context.argv:len() >= 3 and parse_pid(context.argv[1]) >= 0) do limit = parse_pid(context.argv[1]) path_arg = context.argv[2] end
- const lines = file_lines(abspath(path_arg))
+ const lines = file_lines(expand_path(path_arg))
if lines == :nil do puts("head: no such file\n") end
else do
let index = 0
diff --git a/gils/ls.rv b/gils/ls.rv
index f7b9cf7..c069857 100644
--- a/gils/ls.rv
+++ b/gils/ls.rv
@@ -1,7 +1,7 @@
# list a directory
const context = env.ctx
-const target = if context.argv:len() > 1 abspath(context.argv[1]) else wd.path
+const target = if context.argv:len() > 1 expand_path(context.argv[1]) else wd.path
if vfs_owns(target) do vfs_ls(target) end
else do
const count = fs:ls(target)
diff --git a/gils/mkdir.rv b/gils/mkdir.rv
index cb630d1..759544e 100644
--- a/gils/mkdir.rv
+++ b/gils/mkdir.rv
@@ -2,4 +2,4 @@
const context = env.ctx
if context.argv:len() < 2 do puts("usage: mkdir <path>\n") end
-else do fs:mkdir(abspath(context.argv[1])) end
+else do fs:mkdir(expand_path(context.argv[1])) end
diff --git a/gils/mv.rv b/gils/mv.rv
index 95d9a40..d3ecf47 100644
--- a/gils/mv.rv
+++ b/gils/mv.rv
@@ -3,8 +3,8 @@
const context = env.ctx
if context.argv:len() < 3 do puts("usage: mv <source> <destination>\n") end
else do
- const source = abspath(context.argv[1])
- const destination = abspath(context.argv[2])
+ const source = expand_path(context.argv[1])
+ const destination = expand_path(context.argv[2])
const size = fs:size(source)
if size < 0 do puts("mv: #{source}: no such file\n") end
else do
diff --git a/gils/rm.rv b/gils/rm.rv
index 92e21c7..891dc27 100644
--- a/gils/rm.rv
+++ b/gils/rm.rv
@@ -3,4 +3,4 @@
const context = env.ctx
const parsed = arg_name(context.rest, 0)
if parsed.name:len() == 0 do puts("usage: rm <path>\n") end
-else do fs:rm(abspath(parsed.name)) end
+else do fs:rm(expand_path(parsed.name)) end
diff --git a/gils/tail.rv b/gils/tail.rv
index 9cd5647..4a661b4 100644
--- a/gils/tail.rv
+++ b/gils/tail.rv
@@ -19,7 +19,7 @@ else do
let limit = 10
let path_arg = context.argv[1]
if (context.argv:len() >= 3 and parse_pid(context.argv[1]) >= 0) do limit = parse_pid(context.argv[1]) path_arg = context.argv[2] end
- const lines = file_lines(abspath(path_arg))
+ const lines = file_lines(expand_path(path_arg))
if lines == :nil do puts("tail: no such file\n") end
else do
let start = lines:len() - limit
diff --git a/gils/touch.rv b/gils/touch.rv
index 2dd0d8c..84ecca8 100644
--- a/gils/touch.rv
+++ b/gils/touch.rv
@@ -3,7 +3,7 @@
const context = env.ctx
if context.argv:len() < 2 do puts("usage: touch <path>\n") end
else do
- const path = abspath(context.argv[1])
+ const path = expand_path(context.argv[1])
if fs:is_dir(path) do puts("touch: #{path}: is a directory\n") end
else if fs:size(path) < 0 do fs:store(path, "") end
end
diff --git a/gils/tree.rv b/gils/tree.rv
index b052adb..cc41601 100644
--- a/gils/tree.rv
+++ b/gils/tree.rv
@@ -20,7 +20,7 @@ fn tree_walk(path, prefix) do
end
const context = env.ctx
-const target = if context.argv:len() > 1 abspath(context.argv[1]) else wd.path
+const target = if context.argv:len() > 1 expand_path(context.argv[1]) else wd.path
if (vfs_owns(target) and target != "/") do puts("tree: #{target}: virtual dir\n") end
else if (target != "/" and fs:is_dir(target) == :false) do puts("tree: #{target}: not a directory\n") end
else do
diff --git a/gils/wc.rv b/gils/wc.rv
index 2f8be3d..9a184ca 100644
--- a/gils/wc.rv
+++ b/gils/wc.rv
@@ -3,7 +3,7 @@
const context = env.ctx
if context.argv:len() < 2 do puts("usage: wc <path>\n") end
else do
- const path = abspath(context.argv[1])
+ const path = expand_path(context.argv[1])
const size = fs:size(path)
if size < 0 do puts("wc: #{path}: no such file\n") end
else do
diff --git a/kernel/shell.rv b/kernel/shell.rv
index 3e24767..f112889 100644
--- a/kernel/shell.rv
+++ b/kernel/shell.rv
@@ -86,7 +86,7 @@ end
fn cmd_cd(context) do
const arg = if context.argv:len() > 1 context.argv[1] else "/"
- const target = if arg == ".." parent_of(wd.path) else abspath(arg)
+ const target = if arg == ".." parent_of(wd.path) else expand_path(arg)
if target == "/proc" or target == "/bin" or fs:is_dir(target) do wd.path = target end
else do puts("cd: #{arg}: not a directory\n") end
end
@@ -179,7 +179,7 @@ end
fn font_file(name) do
if has_slash(name) do
- const p = abspath(name)
+ const p = expand_path(name)
if (ends_with(p, ".ttf") and fs:size(p) >= 0) return { path = p, kind = :ttf }
if (ends_with(p, ".psf") and fs:size(p) >= 0) return { path = p, kind = :psf }
if fs:size(p ~ ".ttf") >= 0 return { path = p ~ ".ttf", kind = :ttf }
@@ -282,11 +282,42 @@ fn cmd_ps(context) puts("#{proc_count()} process(es) running\n")
fn cmd_echo(context) do if context.line:len() > 5 puts("#{context.line[5..]}\n") else puts("\n") end
fn cmd_mkfs(context) fs:format()
+fn exec_file(target) do
+ let candidates = {}
+ if has_slash(target) do
+ candidates:push(expand_path(target))
+ candidates:push(expand_path(target) ~ ".rv")
+ end
+ else do
+ candidates:push(expand_path(target))
+ candidates:push(expand_path(target) ~ ".rv")
+ candidates:push("/bin/#{target}")
+ candidates:push("/bin/#{target}.rv")
+ end
+ for index in 0..candidates:len() do
+ const path = candidates[index]
+ if fs:size(path) >= 0 do
+ const head = fs:read_bytes(path, 0, 4)
+ if (head:len() >= 4 and head[0]:ascii() == 127 and head[1]:ascii() == 69 and head[2]:ascii() == 76 and head[3]:ascii() == 70) return { path = path, kind = :elf }
+ return { path = path, kind = :script }
+ end
+ end
+ return { path = target, kind = :none }
+end
+
fn cmd_run(context) do
if context.argv:len() <= 1 do list_progs() return :nil end
- const parsed = arg_name(context.rest, 0)
- if run_prog(parsed.name, context.rest[parsed.rest..]) == :true return :hold
- puts("no such program: #{parsed.name}\n")
+ const target = context.argv[1]
+ const info = exec_file(target)
+ if info.kind == :none do puts("run: #{target}: not found\n") return :nil end
+ const sub_argv = context.rest:split(" ")
+ const sub_ctx = make_ctx(context.rest, sub_argv)
+ if info.kind == :script do
+ run_script_path(info.path, target, sub_ctx)
+ return :nil
+ end
+ if load_file_elf(info.path, sub_ctx.rest) == :true return :hold
+ puts("run: #{target}: not executable\n")
return :nil
end
@@ -324,4 +355,4 @@ register("echo <text>", "shell", "print it back", cmd_echo)
register("mkfs", "shell", "format the disk", cmd_mkfs)
register("cd <path>", "gils", "change directory", cmd_cd)
register("pwd", "gils", "print working dir", cmd_pwd)
-register("run [name] [arg]", "shell", "run a program explicitly", cmd_run)
+register("run <path> [args]", "shell", "run a program or revo script", cmd_run)