diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod b/Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod index 36fec1a..0c0420a 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod +++ b/Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod @@ -173,6 +173,27 @@ function table.indexOf(t, value) return -1 end +function table.merge(...) + local args={...} + local out = {} + local outi = {} + + for _,t in ipairs(args) do + for i,v in pairs(t) do + out[i]=v + end + for i,v in ipairs(t) do + outi[#outi+1]=v + end + end + + for i,v in ipairs(outi) do + out[i]=v + end + + return out +end + function string.replace(s, target, repl) local result = {} local i = 1 diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod b/Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod index 9690ba2..36ffcff 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod +++ b/Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod @@ -19,16 +19,128 @@ proxy.attributes = function(path) return { created = 0 } end +local function buildMeta(entries, opts) + opts = opts or {} + local uid = opts.uid or 0 + local gid = opts.gid or 0 + local perms = opts.perms or 0x3F -- default read/write for owner/group/world + + local chunks = {} + table.insert(chunks, string.char(0x02)) -- version header + + for path, target in pairs(entries) do + local name = path + local nameLen = #name + if nameLen > 255 then + error("Filename too long (>255 bytes): "..name) + end + + -- Determine entry type: 0x01 = symlink if target ~= nil and target ~= "" + local entryType = 0x00 + local cmeta = "" + if target and target ~= "" then + entryType = 0x01 + cmeta = target + end + local cmetaLen = #cmeta + if cmetaLen > 255 then + error("cmeta too long (>255 bytes) for "..name) + end + + -- Build entry as bytes + table.insert(chunks, string.char(nameLen)) -- name length + table.insert(chunks, name) -- name + table.insert(chunks, string.char(entryType)) -- entry type + table.insert(chunks, string.char(uid % 256, math.floor(uid/256) % 256)) -- uid + table.insert(chunks, string.char(gid % 256, math.floor(gid/256) % 256)) -- gid + table.insert(chunks, string.char(perms % 256, math.floor(perms/256) % 256)) -- perms + table.insert(chunks, string.char(cmetaLen)) -- cmeta length + if cmetaLen > 0 then + table.insert(chunks, cmeta) + end + end + + return table.concat(chunks) +end + +local function simpleFile(r,w) + return function(op, mode) + if op=="type" then + return "character device" + elseif op=="open" then + if mode=="r" then + return { + read=r + } + elseif mode=="w" then + return { + write=w + } + end + end + end +end + +local function strFile(str) + local dat=tostring(str) + local pos=1 + return simpleFile(function(amount) + pos=pos+amount + return dat:sub(pos-amount, pos) + end,function() error("EACCES") end) +end + +local function newtaskproxy(task) + local files,siblings,children={},{},{} + if task.fd[0] then files["0"]=task.fd[0].path end + for i,v in ipairs(task.fd) do + files[tostring(i)]=tostring(v.path) + end + for i,v in ipairs(task.siblings) do + siblings[tostring(v.pid)]="/proc/"..tostring(v.pid) + end + for i,v in ipairs(task.children) do + children[tostring(v.pid)]="/proc/"..tostring(v.pid) + end + return { + [".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid)})), + uid=strFile(task.uid), + comm=strFile(task.name), + fd={ + [".meta"]=strFile(buildMeta(files)) + }, + siblings={ + [".meta"]=strFile(buildMeta(siblings)) + }, + children={ + [".meta"]=strFile(buildMeta(children)) + } + } +end + function proxy:open(path, mode) local steps = kernel.vfs.splitPath(path) local step = data - for i=1, #steps-1 do - local dat = step[steps[i]] - if type(dat) ~= "table" then error("ENFILE") end - step=dat - end - if type(step[steps[#steps]]) == "function" then - return step[steps[#steps]]("open", mode) + if tonumber(steps[1]) then + local task=kernel.tasks[tostring(steps[1])] + local step = newtaskproxy(task) + for i=2, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("open", mode) + end + else + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("open", mode) + end end error("ENFILE") end @@ -39,16 +151,33 @@ function proxy:type(path, mode) if #steps == 0 then return "directory" end - for i=1, #steps-1 do - local dat = step[steps[i]] - if type(dat) ~= "table" then error("ENFILE") end - step=dat - end - if type(step[steps[#steps]]) == "function" then - return step[steps[#steps]]("type", mode) - end - if type(step[steps[#steps]]) == "table" then - return "directory" + if tonumber(steps[1]) then + local task=kernel.tasks[steps[1]] + if #steps==1 then return "directory" end + local step = newtaskproxy(task) + for i=2, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("type", mode) + end + if type(step[steps[#steps]]) == "table" then + return "directory" + end + else + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("type", mode) + end + if type(step[steps[#steps]]) == "table" then + return "directory" + end end error("ENOENT") end @@ -57,15 +186,29 @@ function proxy:list(path) local steps = kernel.vfs.splitPath(path) local step = data if #steps == 0 then - return table.keys(data) + return table.merge(table.keys(data),table.keys(kernel.tasks)) end - for i=1, #steps-1 do - local dat = step[steps[i]] - if type(dat) ~= "table" then error("ENOENT") end - step=dat - end - if type(step[steps[#steps]]) == "table" then - return table.keys(step[steps[#steps]]) + if tonumber(steps[1]) then + local task=kernel.tasks[steps[1]] + local step = newtaskproxy(task) + if #steps==1 then return table.keys(step) end + for i=2, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENOENT") end + step=dat + end + if type(step[steps[#steps]]) == "table" then + return table.keys(step[steps[#steps]]) + end + else + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENOENT") end + step=dat + end + if type(step[steps[#steps]]) == "table" then + return table.keys(step[steps[#steps]]) + end end error("ENOENT") end @@ -77,6 +220,7 @@ function proxy:fileExists(path) return ok end +data.uptime=simpleFile(function()return tostring(kernel.computer:getUptime())end,function()error("EACCES")end) kernel.procfs={} kernel.procfs.data=data kernel.procfs.proxy=proxy diff --git a/Src/hysh/bin/ls b/Src/hysh/bin/ls index be98f0e..cf54cc4 100644 --- a/Src/hysh/bin/ls +++ b/Src/hysh/bin/ls @@ -148,7 +148,7 @@ if cloptions.l then syscall.devctl(1, "sfgc", 1) end elseif isDir then - syscall.devctl(1, "sfgc", 4) + syscall.devctl(1, "sfgc", 14) printInline(v) syscall.devctl(1, "sfgc", 1) else @@ -177,7 +177,7 @@ for i, v in ipairs(list) do if isSym then syscall.devctl(1, "sfgc", 6) elseif isDir then - syscall.devctl(1, "sfgc", 4) + syscall.devctl(1, "sfgc", 14) else local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1) syscall.devctl(1, "sfgc", isExec and 3 or 1) diff --git a/install/installcc.lua b/install/installcc.lua new file mode 100644 index 0000000..1ee515b --- /dev/null +++ b/install/installcc.lua @@ -0,0 +1,2 @@ +print("Hello, World!") +sleep() \ No newline at end of file diff --git a/manifest.lua b/manifest.lua index 9fa2a2e..f6c8716 100644 --- a/manifest.lua +++ b/manifest.lua @@ -577,6 +577,11 @@ table.values=function(tabl) end --- @return string table.serialize=function(tabl) end +--- Returns a merged table with a and b +--- @param ... table +--- @return table +table.merge=function(...) end + --- Gets prefix of string with suffix --- @param str string --- @param suffix string